|
3717
|
136
|
19
|
2026-05-07T12:37:24.713291+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157444713_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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring start {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring end {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:19] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] 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":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
Sync Changes
Hide This Notification
Code changed:
Hide
2
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"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":"Search Backward","depth":4,"bounds":{"left":0.7130984,"top":0.07821229,"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":"Search Forward","depth":4,"bounds":{"left":0.72174203,"top":0.07821229,"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":"Match сase","depth":4,"bounds":{"left":0.73038566,"top":0.07821229,"width":0.032247342,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"bounds":{"left":0.76263297,"top":0.07821229,"width":0.023271276,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"bounds":{"left":0.7859042,"top":0.07821229,"width":0.022938829,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"bounds":{"left":0.8088431,"top":0.08220271,"width":0.0019946808,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.97539896,"top":0.07821229,"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":"AXTextArea","text":"[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring start {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring end {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] 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\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}","depth":4,"bounds":{"left":0.52859044,"top":0.10454908,"width":0.47140956,"height":0.8747007},"on_screen":true,"lines":[{"char_start":918,"char_count":324,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":1242,"char_count":203,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":1445,"char_count":378,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":1823,"char_count":326,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":2149,"char_count":380,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":2529,"char_count":162,"bounds":{"left":0.53025264,"top":0.0,"width":0.41722074,"height":0.014365523}},{"char_start":2691,"char_count":160,"bounds":{"left":0.53025264,"top":0.015961692,"width":0.41223404,"height":0.014365523}},{"char_start":2851,"char_count":326,"bounds":{"left":0.53025264,"top":0.033519555,"width":0.46974736,"height":0.014365523}},{"char_start":3177,"char_count":380,"bounds":{"left":0.53025264,"top":0.051077414,"width":0.46974736,"height":0.014365523}},{"char_start":3557,"char_count":321,"bounds":{"left":0.53025264,"top":0.06863528,"width":0.46974736,"height":0.014365523}},{"char_start":3878,"char_count":206,"bounds":{"left":0.53025264,"top":0.08619314,"width":0.46974736,"height":0.014365523}},{"char_start":4084,"char_count":220,"bounds":{"left":0.53025264,"top":0.103751,"width":0.46974736,"height":0.014365523}},{"char_start":4304,"char_count":373,"bounds":{"left":0.53025264,"top":0.121308856,"width":0.46974736,"height":0.014365523}}],"value":"[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring start {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring end {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] 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\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}","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.4820479,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":4,"bounds":{"left":0.49202126,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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}]...
|
-1472440894006629353
|
6666846822792300644
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring start {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring end {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:19] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] 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":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
Sync Changes
Hide This Notification
Code changed:
Hide
2
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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...
|
3716
|
NULL
|
NULL
|
NULL
|
|
3716
|
136
|
18
|
2026-05-07T12:37:20.396834+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157440396_m2.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/Service.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring start {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring end {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:19] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] 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":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
Sync Changes
Hide This Notification
Code changed:
Hide
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['r...
|
[{"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"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":"Search Backward","depth":4,"bounds":{"left":0.7130984,"top":0.07821229,"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":"Search Forward","depth":4,"bounds":{"left":0.72174203,"top":0.07821229,"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":"Match сase","depth":4,"bounds":{"left":0.73038566,"top":0.07821229,"width":0.032247342,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"bounds":{"left":0.76263297,"top":0.07821229,"width":0.023271276,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"bounds":{"left":0.7859042,"top":0.07821229,"width":0.022938829,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"bounds":{"left":0.8088431,"top":0.08220271,"width":0.0019946808,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.97539896,"top":0.07821229,"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":"AXTextArea","text":"[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring start {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring end {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] 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\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}","depth":4,"bounds":{"left":0.52859044,"top":0.10454908,"width":0.47140956,"height":0.8747007},"on_screen":true,"lines":[{"char_start":918,"char_count":324,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":1242,"char_count":203,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":1445,"char_count":378,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":1823,"char_count":326,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":2149,"char_count":380,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":2529,"char_count":162,"bounds":{"left":0.53025264,"top":0.0,"width":0.41722074,"height":0.014365523}},{"char_start":2691,"char_count":160,"bounds":{"left":0.53025264,"top":0.015961692,"width":0.41223404,"height":0.014365523}},{"char_start":2851,"char_count":326,"bounds":{"left":0.53025264,"top":0.033519555,"width":0.46974736,"height":0.014365523}},{"char_start":3177,"char_count":380,"bounds":{"left":0.53025264,"top":0.051077414,"width":0.46974736,"height":0.014365523}},{"char_start":3557,"char_count":321,"bounds":{"left":0.53025264,"top":0.06863528,"width":0.46974736,"height":0.014365523}},{"char_start":3878,"char_count":206,"bounds":{"left":0.53025264,"top":0.08619314,"width":0.46974736,"height":0.014365523}},{"char_start":4084,"char_count":220,"bounds":{"left":0.53025264,"top":0.103751,"width":0.46974736,"height":0.014365523}},{"char_start":4304,"char_count":373,"bounds":{"left":0.53025264,"top":0.121308856,"width":0.46974736,"height":0.014365523}}],"value":"[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring start {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring end {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}\n[2026-05-07 12:37:19] 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\":\"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e\",\"trace_id\":\"d35331c8-5bc2-453e-a064-52c939ade38b\"}","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":"8","depth":4,"bounds":{"left":0.46176863,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"bounds":{"left":0.47174203,"top":0.19952115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.48337767,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","depth":4,"bounds":{"left":0.49268618,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.5049867,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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}]...
|
5752532236408100640
|
-465722764674590617
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring start {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring end {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:19] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
[2026-05-07 12:37:19] 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":"0ff4c783-54ce-44a7-abfb-0d2ccf78b33e","trace_id":"d35331c8-5bc2-453e-a064-52c939ade38b"}
Sync Changes
Hide This Notification
Code changed:
Hide
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['r...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3715
|
135
|
16
|
2026-05-07T12:37:19.249870+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157439249_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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring start {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring end {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
Sync Changes
Hide This Notification
Code changed:
Hide
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need to...
|
[{"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":"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":"Hubspot","depth":4,"on_screen":true,"value":"Hubspot","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":"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":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search All","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Backward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Forward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match сase","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"on_screen":true,"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":"AXTextArea","text":"[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring start {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring end {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring start {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring end {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}","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":"8","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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}]...
|
-3248289386434438233
|
-465722764674590617
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring start {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring end {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
Sync Changes
Hide This Notification
Code changed:
Hide
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need to...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3714
|
136
|
17
|
2026-05-07T12:37:18.247823+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157438247_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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring start {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring end {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
Sync Changes
Hide This Notification
Code changed:
Hide
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need 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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"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":"Search Backward","depth":4,"bounds":{"left":0.7130984,"top":0.07821229,"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":"Search Forward","depth":4,"bounds":{"left":0.72174203,"top":0.07821229,"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":"Match сase","depth":4,"bounds":{"left":0.73038566,"top":0.07821229,"width":0.032247342,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"bounds":{"left":0.76263297,"top":0.07821229,"width":0.023271276,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"bounds":{"left":0.7859042,"top":0.07821229,"width":0.022938829,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"bounds":{"left":0.8088431,"top":0.08220271,"width":0.0019946808,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.97539896,"top":0.07821229,"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":"AXTextArea","text":"[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring start {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring end {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}","depth":4,"bounds":{"left":0.52859044,"top":0.10454908,"width":0.47140956,"height":0.8747007},"on_screen":true,"lines":[{"char_start":918,"char_count":324,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":1242,"char_count":203,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":1445,"char_count":378,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":1823,"char_count":326,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":2149,"char_count":380,"bounds":{"left":0.53025264,"top":0.0,"width":0.46974736,"height":0.014365523}},{"char_start":2529,"char_count":162,"bounds":{"left":0.53025264,"top":0.0,"width":0.41722074,"height":0.014365523}},{"char_start":2691,"char_count":160,"bounds":{"left":0.53025264,"top":0.015961692,"width":0.41223404,"height":0.014365523}},{"char_start":2851,"char_count":326,"bounds":{"left":0.53025264,"top":0.033519555,"width":0.46974736,"height":0.014365523}},{"char_start":3177,"char_count":378,"bounds":{"left":0.53025264,"top":0.051077414,"width":0.46974736,"height":0.014365523}}],"value":"[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"61149f3e-9706-4ebc-afd1-3c48ba89f0e3\",\"trace_id\":\"1f35b6a1-ac0e-4bfd-be09-a730c3209e43\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37:07] 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\":\"8d159556-e171-42b6-8619-39c52d489e85\",\"trace_id\":\"410be53d-a74d-416e-ae1d-5c3f2272aa08\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37: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\":\"417bbc90-fd43-4136-b5eb-aaba87bb74f9\",\"trace_id\":\"6a773999-275d-4d1f-b846-fed74c7c5c69\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring start {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:13] local.NOTICE: Monitoring end {\"correlation_id\":\"e8064350-9a09-4ace-8865-1d82d5ce27e4\",\"trace_id\":\"9da060a9-b514-4553-9097-49c0aee4eafd\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}\n[2026-05-07 12:37:15] 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\":\"ff0ee961-0be2-4514-8867-c526c45d66e8\",\"trace_id\":\"689f8009-70c8-4a2f-b029-1d0dff4eab4f\"}","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":"8","depth":4,"bounds":{"left":0.46176863,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"bounds":{"left":0.47174203,"top":0.19952115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.48337767,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","depth":4,"bounds":{"left":0.49268618,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.5049867,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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}]...
|
-3248289386434438233
|
-465722764674590617
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:05] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"61149f3e-9706-4ebc-afd1-3c48ba89f0e3","trace_id":"1f35b6a1-ac0e-4bfd-be09-a730c3209e43"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37:07] 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":"8d159556-e171-42b6-8619-39c52d489e85","trace_id":"410be53d-a74d-416e-ae1d-5c3f2272aa08"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37: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":"417bbc90-fd43-4136-b5eb-aaba87bb74f9","trace_id":"6a773999-275d-4d1f-b846-fed74c7c5c69"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring start {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:13] local.NOTICE: Monitoring end {"correlation_id":"e8064350-9a09-4ace-8865-1d82d5ce27e4","trace_id":"9da060a9-b514-4553-9097-49c0aee4eafd"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
[2026-05-07 12:37:15] 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":"ff0ee961-0be2-4514-8867-c526c45d66e8","trace_id":"689f8009-70c8-4a2f-b029-1d0dff4eab4f"}
Sync Changes
Hide This Notification
Code changed:
Hide
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need to...
|
3712
|
NULL
|
NULL
|
NULL
|
|
3696
|
135
|
6
|
2026-05-07T12:36:16.050018+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157376050_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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:34:39] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {"pid":32728,"workerId":"","target":"activities"} {"correlation_id":"2dc91923-2a7f-4251-9ddd-5663739b2850","trace_id":"2bc19bcd-96d0-45d9-b13c-1c1dba7aff9f"}
[2026-05-07 12:35:04] 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":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:04] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:04] 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":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0","trace_id":"da1dcdd2-a656-4e5e-8a4b-c714d1175381"}
[2026-05-07 12:35:06] 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":"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0","trace_id":"da1dcdd2-a656-4e5e-8a4b-c714d1175381"}
[2026-05-07 12:35:08] local.NOTICE: Monitoring start {"correlation_id":"cc05b2e5-39a2-4fb1-8859-871c3d987279","trace_id":"168cc802-ec5c-4bfd-bfa8-45571e2946cc"}
[2026-05-07 12:35:08] local.NOTICE: Monitoring end {"correlation_id":"cc05b2e5-39a2-4fb1-8859-871c3d987279","trace_id":"168cc802-ec5c-4bfd-bfa8-45571e2946cc"}
[2026-05-07 12:35: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":"8fdc327b-c3dd-4eed-b9a9-00cc263ed461","trace_id":"2b164538-6384-413e-a68b-589aabda4af3"}
[2026-05-07 12:35: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":"8fdc327b-c3dd-4eed-b9a9-00cc263ed461","trace_id":"2b164538-6384-413e-a68b-589aabda4af3"}
[2026-05-07 12:35: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":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:12] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:12] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35: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":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ef495688-effa-4ee7-9b81-ccb161f7c3bf","trace_id":"26eabbbc-6174-434e-9756-1b84825f03ab"}
[2026-05-07 12:35:14] 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":"ef495688-effa-4ee7-9b81-ccb161f7c3bf","trace_id":"26eabbbc-6174-434e-9756-1b84825f03ab"}
[2026-05-07 12:35:16] 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":"aac3580d-654c-4490-ab7d-7d91ff1ce423","trace_id":"c35dd663-0ae1-4d03-b56d-120bf7292ecb"}
[2026-05-07 12:35:16] 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":"aac3580d-654c-4490-ab7d-7d91ff1ce423","trace_id":"c35dd663-0ae1-4d03-b56d-120bf7292ecb"}
[2026-05-07 12:35:18] 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":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:18] local.INFO: Running pre-meeting notification command {"correlation_id":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:18] 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":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:21] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] 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":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesEnded {"from":"12:30","to":"12:35"} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {"from":"02:25","to":"02:30"} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] 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":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:31] local.NOTICE: Repairing HubSpot tokens start {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":59,"provider":"hubspot","refreshToken":"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35: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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":306,"provider":"hubspot","refreshToken":"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] 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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: Trying to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1372,"provider":"hubspot","refreshToken":"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35: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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:36] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"de4aa643-9d23-4d24-8c6a-ba951496144e","trace_id":"169c2fe6-d32d-45e5-9682-6ae91ce0396f"}
[2026-05-07 12:35:36] 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":"e37299b2-0176-4eac-815f-0caabf7af320","trace_id":"c47be302-8931-4988-a55d-3560a61143b6"}
[2026-05-07 12:35:36] 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":"de4aa643-9d23-4d24-8c6a-ba951496144e","trace_id":"169c2fe6-d32d-45e5-9682-6ae91ce0396f"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Command] Starting polling service {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Service starting {"memory_limit":"256M","max_execution_time":"0","initial_memory_mb":62.0} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Acquired polling lock {"expires_at":"2026-05-07T12:37:36.789343Z"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"[URL_WITH_CREDENTIALS] CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
...
|
[{"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":"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":"Hubspot","depth":4,"on_screen":true,"value":"Hubspot","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":"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":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search All","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Backward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Forward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match сase","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"on_screen":true,"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":"AXTextArea","text":"[2026-05-07 12:34:39] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {\"pid\":32728,\"workerId\":\"\",\"target\":\"activities\"} {\"correlation_id\":\"2dc91923-2a7f-4251-9ddd-5663739b2850\",\"trace_id\":\"2bc19bcd-96d0-45d9-b13c-1c1dba7aff9f\"}\n[2026-05-07 12:35:04] 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\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:04] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:04] 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\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0\",\"trace_id\":\"da1dcdd2-a656-4e5e-8a4b-c714d1175381\"}\n[2026-05-07 12:35:06] 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\":\"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0\",\"trace_id\":\"da1dcdd2-a656-4e5e-8a4b-c714d1175381\"}\n[2026-05-07 12:35:08] local.NOTICE: Monitoring start {\"correlation_id\":\"cc05b2e5-39a2-4fb1-8859-871c3d987279\",\"trace_id\":\"168cc802-ec5c-4bfd-bfa8-45571e2946cc\"}\n[2026-05-07 12:35:08] local.NOTICE: Monitoring end {\"correlation_id\":\"cc05b2e5-39a2-4fb1-8859-871c3d987279\",\"trace_id\":\"168cc802-ec5c-4bfd-bfa8-45571e2946cc\"}\n[2026-05-07 12:35: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\":\"8fdc327b-c3dd-4eed-b9a9-00cc263ed461\",\"trace_id\":\"2b164538-6384-413e-a68b-589aabda4af3\"}\n[2026-05-07 12:35: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\":\"8fdc327b-c3dd-4eed-b9a9-00cc263ed461\",\"trace_id\":\"2b164538-6384-413e-a68b-589aabda4af3\"}\n[2026-05-07 12:35: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\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35: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\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ef495688-effa-4ee7-9b81-ccb161f7c3bf\",\"trace_id\":\"26eabbbc-6174-434e-9756-1b84825f03ab\"}\n[2026-05-07 12:35:14] 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\":\"ef495688-effa-4ee7-9b81-ccb161f7c3bf\",\"trace_id\":\"26eabbbc-6174-434e-9756-1b84825f03ab\"}\n[2026-05-07 12:35:16] 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\":\"aac3580d-654c-4490-ab7d-7d91ff1ce423\",\"trace_id\":\"c35dd663-0ae1-4d03-b56d-120bf7292ecb\"}\n[2026-05-07 12:35:16] 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\":\"aac3580d-654c-4490-ab7d-7d91ff1ce423\",\"trace_id\":\"c35dd663-0ae1-4d03-b56d-120bf7292ecb\"}\n[2026-05-07 12:35:18] 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\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:18] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:18] 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\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] 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\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:30\",\"to\":\"12:35\"} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:25\",\"to\":\"02:30\"} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] 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\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:31] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35: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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] 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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35: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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"de4aa643-9d23-4d24-8c6a-ba951496144e\",\"trace_id\":\"169c2fe6-d32d-45e5-9682-6ae91ce0396f\"}\n[2026-05-07 12:35:36] 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\":\"e37299b2-0176-4eac-815f-0caabf7af320\",\"trace_id\":\"c47be302-8931-4988-a55d-3560a61143b6\"}\n[2026-05-07 12:35:36] 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\":\"de4aa643-9d23-4d24-8c6a-ba951496144e\",\"trace_id\":\"169c2fe6-d32d-45e5-9682-6ae91ce0396f\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:37:36.789343Z\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] 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\":\"e37299b2-0176-4eac-815f-0caabf7af320\",\"trace_id\":\"c47be302-8931-4988-a55d-3560a61143b6\"}\n[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36: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\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36: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\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0ef13206-7c40-464d-a0af-bbaa723080ff\",\"trace_id\":\"fdc7e389-cf4c-4c13-a27d-199959e4691f\"}\n[2026-05-07 12:36: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\":\"0ef13206-7c40-464d-a0af-bbaa723080ff\",\"trace_id\":\"fdc7e389-cf4c-4c13-a27d-199959e4691f\"}\n[2026-05-07 12:36:13] local.NOTICE: Monitoring start {\"correlation_id\":\"87589fd8-76e4-41f4-afe5-f442201ab71c\",\"trace_id\":\"ad59c3de-6d0c-4487-b721-0dfcba13ba89\"}\n[2026-05-07 12:36:13] local.NOTICE: Monitoring end {\"correlation_id\":\"87589fd8-76e4-41f4-afe5-f442201ab71c\",\"trace_id\":\"ad59c3de-6d0c-4487-b721-0dfcba13ba89\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:34:39] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {\"pid\":32728,\"workerId\":\"\",\"target\":\"activities\"} {\"correlation_id\":\"2dc91923-2a7f-4251-9ddd-5663739b2850\",\"trace_id\":\"2bc19bcd-96d0-45d9-b13c-1c1dba7aff9f\"}\n[2026-05-07 12:35:04] 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\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:04] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:04] 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\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0\",\"trace_id\":\"da1dcdd2-a656-4e5e-8a4b-c714d1175381\"}\n[2026-05-07 12:35:06] 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\":\"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0\",\"trace_id\":\"da1dcdd2-a656-4e5e-8a4b-c714d1175381\"}\n[2026-05-07 12:35:08] local.NOTICE: Monitoring start {\"correlation_id\":\"cc05b2e5-39a2-4fb1-8859-871c3d987279\",\"trace_id\":\"168cc802-ec5c-4bfd-bfa8-45571e2946cc\"}\n[2026-05-07 12:35:08] local.NOTICE: Monitoring end {\"correlation_id\":\"cc05b2e5-39a2-4fb1-8859-871c3d987279\",\"trace_id\":\"168cc802-ec5c-4bfd-bfa8-45571e2946cc\"}\n[2026-05-07 12:35: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\":\"8fdc327b-c3dd-4eed-b9a9-00cc263ed461\",\"trace_id\":\"2b164538-6384-413e-a68b-589aabda4af3\"}\n[2026-05-07 12:35: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\":\"8fdc327b-c3dd-4eed-b9a9-00cc263ed461\",\"trace_id\":\"2b164538-6384-413e-a68b-589aabda4af3\"}\n[2026-05-07 12:35: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\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35: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\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ef495688-effa-4ee7-9b81-ccb161f7c3bf\",\"trace_id\":\"26eabbbc-6174-434e-9756-1b84825f03ab\"}\n[2026-05-07 12:35:14] 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\":\"ef495688-effa-4ee7-9b81-ccb161f7c3bf\",\"trace_id\":\"26eabbbc-6174-434e-9756-1b84825f03ab\"}\n[2026-05-07 12:35:16] 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\":\"aac3580d-654c-4490-ab7d-7d91ff1ce423\",\"trace_id\":\"c35dd663-0ae1-4d03-b56d-120bf7292ecb\"}\n[2026-05-07 12:35:16] 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\":\"aac3580d-654c-4490-ab7d-7d91ff1ce423\",\"trace_id\":\"c35dd663-0ae1-4d03-b56d-120bf7292ecb\"}\n[2026-05-07 12:35:18] 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\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:18] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:18] 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\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] 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\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:30\",\"to\":\"12:35\"} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:25\",\"to\":\"02:30\"} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] 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\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:31] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35: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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] 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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35: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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"de4aa643-9d23-4d24-8c6a-ba951496144e\",\"trace_id\":\"169c2fe6-d32d-45e5-9682-6ae91ce0396f\"}\n[2026-05-07 12:35:36] 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\":\"e37299b2-0176-4eac-815f-0caabf7af320\",\"trace_id\":\"c47be302-8931-4988-a55d-3560a61143b6\"}\n[2026-05-07 12:35:36] 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\":\"de4aa643-9d23-4d24-8c6a-ba951496144e\",\"trace_id\":\"169c2fe6-d32d-45e5-9682-6ae91ce0396f\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:37:36.789343Z\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] 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\":\"e37299b2-0176-4eac-815f-0caabf7af320\",\"trace_id\":\"c47be302-8931-4988-a55d-3560a61143b6\"}\n[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36: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\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36: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\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0ef13206-7c40-464d-a0af-bbaa723080ff\",\"trace_id\":\"fdc7e389-cf4c-4c13-a27d-199959e4691f\"}\n[2026-05-07 12:36: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\":\"0ef13206-7c40-464d-a0af-bbaa723080ff\",\"trace_id\":\"fdc7e389-cf4c-4c13-a27d-199959e4691f\"}\n[2026-05-07 12:36:13] local.NOTICE: Monitoring start {\"correlation_id\":\"87589fd8-76e4-41f4-afe5-f442201ab71c\",\"trace_id\":\"ad59c3de-6d0c-4487-b721-0dfcba13ba89\"}\n[2026-05-07 12:36:13] local.NOTICE: Monitoring end {\"correlation_id\":\"87589fd8-76e4-41f4-afe5-f442201ab71c\",\"trace_id\":\"ad59c3de-6d0c-4487-b721-0dfcba13ba89\"}","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":"8","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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}]...
|
-1966321079585168372
|
-3269213808139494299
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:34:39] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {"pid":32728,"workerId":"","target":"activities"} {"correlation_id":"2dc91923-2a7f-4251-9ddd-5663739b2850","trace_id":"2bc19bcd-96d0-45d9-b13c-1c1dba7aff9f"}
[2026-05-07 12:35:04] 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":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:04] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:04] 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":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0","trace_id":"da1dcdd2-a656-4e5e-8a4b-c714d1175381"}
[2026-05-07 12:35:06] 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":"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0","trace_id":"da1dcdd2-a656-4e5e-8a4b-c714d1175381"}
[2026-05-07 12:35:08] local.NOTICE: Monitoring start {"correlation_id":"cc05b2e5-39a2-4fb1-8859-871c3d987279","trace_id":"168cc802-ec5c-4bfd-bfa8-45571e2946cc"}
[2026-05-07 12:35:08] local.NOTICE: Monitoring end {"correlation_id":"cc05b2e5-39a2-4fb1-8859-871c3d987279","trace_id":"168cc802-ec5c-4bfd-bfa8-45571e2946cc"}
[2026-05-07 12:35: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":"8fdc327b-c3dd-4eed-b9a9-00cc263ed461","trace_id":"2b164538-6384-413e-a68b-589aabda4af3"}
[2026-05-07 12:35: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":"8fdc327b-c3dd-4eed-b9a9-00cc263ed461","trace_id":"2b164538-6384-413e-a68b-589aabda4af3"}
[2026-05-07 12:35: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":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:12] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:12] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35: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":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ef495688-effa-4ee7-9b81-ccb161f7c3bf","trace_id":"26eabbbc-6174-434e-9756-1b84825f03ab"}
[2026-05-07 12:35:14] 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":"ef495688-effa-4ee7-9b81-ccb161f7c3bf","trace_id":"26eabbbc-6174-434e-9756-1b84825f03ab"}
[2026-05-07 12:35:16] 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":"aac3580d-654c-4490-ab7d-7d91ff1ce423","trace_id":"c35dd663-0ae1-4d03-b56d-120bf7292ecb"}
[2026-05-07 12:35:16] 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":"aac3580d-654c-4490-ab7d-7d91ff1ce423","trace_id":"c35dd663-0ae1-4d03-b56d-120bf7292ecb"}
[2026-05-07 12:35:18] 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":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:18] local.INFO: Running pre-meeting notification command {"correlation_id":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:18] 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":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:21] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] 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":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesEnded {"from":"12:30","to":"12:35"} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {"from":"02:25","to":"02:30"} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] 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":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:31] local.NOTICE: Repairing HubSpot tokens start {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":59,"provider":"hubspot","refreshToken":"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35: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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":306,"provider":"hubspot","refreshToken":"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] 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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: Trying to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1372,"provider":"hubspot","refreshToken":"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35: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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:36] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"de4aa643-9d23-4d24-8c6a-ba951496144e","trace_id":"169c2fe6-d32d-45e5-9682-6ae91ce0396f"}
[2026-05-07 12:35:36] 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":"e37299b2-0176-4eac-815f-0caabf7af320","trace_id":"c47be302-8931-4988-a55d-3560a61143b6"}
[2026-05-07 12:35:36] 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":"de4aa643-9d23-4d24-8c6a-ba951496144e","trace_id":"169c2fe6-d32d-45e5-9682-6ae91ce0396f"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Command] Starting polling service {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Service starting {"memory_limit":"256M","max_execution_time":"0","initial_memory_mb":62.0} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Acquired polling lock {"expires_at":"2026-05-07T12:37:36.789343Z"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"[URL_WITH_CREDENTIALS] CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3695
|
136
|
8
|
2026-05-07T12:36:15.986796+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157375986_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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:34:39] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {"pid":32728,"workerId":"","target":"activities"} {"correlation_id":"2dc91923-2a7f-4251-9ddd-5663739b2850","trace_id":"2bc19bcd-96d0-45d9-b13c-1c1dba7aff9f"}
[2026-05-07 12:35:04] 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":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:04] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:04] 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":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0","trace_id":"da1dcdd2-a656-4e5e-8a4b-c714d1175381"}
[2026-05-07 12:35:06] 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":"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0","trace_id":"da1dcdd2-a656-4e5e-8a4b-c714d1175381"}
[2026-05-07 12:35:08] local.NOTICE: Monitoring start {"correlation_id":"cc05b2e5-39a2-4fb1-8859-871c3d987279","trace_id":"168cc802-ec5c-4bfd-bfa8-45571e2946cc"}
[2026-05-07 12:35:08] local.NOTICE: Monitoring end {"correlation_id":"cc05b2e5-39a2-4fb1-8859-871c3d987279","trace_id":"168cc802-ec5c-4bfd-bfa8-45571e2946cc"}
[2026-05-07 12:35: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":"8fdc327b-c3dd-4eed-b9a9-00cc263ed461","trace_id":"2b164538-6384-413e-a68b-589aabda4af3"}
[2026-05-07 12:35: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":"8fdc327b-c3dd-4eed-b9a9-00cc263ed461","trace_id":"2b164538-6384-413e-a68b-589aabda4af3"}
[2026-05-07 12:35: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":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:12] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:12] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35: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":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ef495688-effa-4ee7-9b81-ccb161f7c3bf","trace_id":"26eabbbc-6174-434e-9756-1b84825f03ab"}
[2026-05-07 12:35:14] 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":"ef495688-effa-4ee7-9b81-ccb161f7c3bf","trace_id":"26eabbbc-6174-434e-9756-1b84825f03ab"}
[2026-05-07 12:35:16] 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":"aac3580d-654c-4490-ab7d-7d91ff1ce423","trace_id":"c35dd663-0ae1-4d03-b56d-120bf7292ecb"}
[2026-05-07 12:35:16] 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":"aac3580d-654c-4490-ab7d-7d91ff1ce423","trace_id":"c35dd663-0ae1-4d03-b56d-120bf7292ecb"}
[2026-05-07 12:35:18] 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":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:18] local.INFO: Running pre-meeting notification command {"correlation_id":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:18] 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":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:21] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] 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":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesEnded {"from":"12:30","to":"12:35"} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {"from":"02:25","to":"02:30"} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] 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":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:31] local.NOTICE: Repairing HubSpot tokens start {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":59,"provider":"hubspot","refreshToken":"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35: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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":306,"provider":"hubspot","refreshToken":"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] 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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: Trying to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1372,"provider":"hubspot","refreshToken":"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35: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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:36] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"de4aa643-9d23-4d24-8c6a-ba951496144e","trace_id":"169c2fe6-d32d-45e5-9682-6ae91ce0396f"}
[2026-05-07 12:35:36] 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":"e37299b2-0176-4eac-815f-0caabf7af320","trace_id":"c47be302-8931-4988-a55d-3560a61143b6"}
[2026-05-07 12:35:36] 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":"de4aa643-9d23-4d24-8c6a-ba951496144e","trace_id":"169c2fe6-d32d-45e5-9682-6ae91ce0396f"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Command] Starting polling service {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Service starting {"memory_limit":"256M","max_execution_time":"0","initial_memory_mb":62.0} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Acquired polling lock {"expires_at":"2026-05-07T12:37:36.789343Z"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] 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":"e37299b2-0176-4eac-815f-0caabf7af320","trace_id":"c47be302-8931-4988-a55d-3560a61143b6"}
[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4","trace_id":"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02"}
[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4","trace_id":"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02"}
[2026-05-07 12:35:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4","trace_id":"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02"}
[2026-05-07 12:35:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4","trace_id":"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02"}
[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {"expires_in":1800,"cached_for":1500} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"4374f995-b892-49b7-9eaf-d80bcf1eaec2","trace_id":"a0f4c391-5090-49ea-8a57-80d06a576d54"}
[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"4374f995-b892-49b7-9eaf-d80bcf1eaec2","trace_id":"a0f4c391-5090-49ea-8a57-80d06a576d54"}
[2026-05-07 12:35:58] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"4374f995-b892-49b7-9eaf-d80bcf1eaec2","trace_id":"a0f4c391-5090-49ea-8a57-80d06a576d54"}
[2026-05-07 12:35:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"4374f995-b892-49b7-9eaf-d80bcf1eaec2","trace_id":"a0f4c391-5090-49ea-8a57-80d06a576d54"}
[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:36:02] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:36: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":"b6fa3d42-16e4-4eab-b363-13c6cfb7b814","trace_id":"590f9853-355e-49a5-ae3b-99a357cb7f43"}
[2026-05-07 12:36:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"b6fa3d42-16e4-4eab-b363-13c6cfb7b814","trace_id":"590f9853-355e-49a5-ae3b-99a357cb7f43"}
[2026-05-07 12:36: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":"b6fa3d42-16e4-4eab-b363-13c6cfb7b814","trace_id":"590f9853-355e-49a5-ae3b-99a357cb7f43"}
[2026-05-07 12:36:09] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0ef13206-7c40-464d-a0af-bbaa723080ff","trace_id":"fdc7e389-cf4c-4c13-a27d-199959e4691f"}
[2026-05-07 12:36: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":"0ef13206-7c40-464d-a0af-bbaa723080ff","trace_id":"fdc7e389-cf4c-4c13-a27d-199959e4691f"}
[2026-05-07 12:36:13] local.NOTICE: Monitoring start {"correlation_id":"87589fd8-76e4-41f4-afe5-f442201ab71c","trace_id":"ad59c3de-6d0c-4487-b721-0dfcba13ba89"}
[2026-05-07 12:36:13] local.NOTICE: Monitoring end {"correlation_id":"87589fd8-76e4-41f4-afe5-f442201ab71c","trace_id":"ad59c3de-6d0c-4487-b721-0dfcba13ba89"}...
|
[{"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"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":"Search Backward","depth":4,"bounds":{"left":0.7130984,"top":0.07821229,"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":"Search Forward","depth":4,"bounds":{"left":0.72174203,"top":0.07821229,"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":"Match сase","depth":4,"bounds":{"left":0.73038566,"top":0.07821229,"width":0.032247342,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"bounds":{"left":0.76263297,"top":0.07821229,"width":0.023271276,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"bounds":{"left":0.7859042,"top":0.07821229,"width":0.022938829,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"bounds":{"left":0.8088431,"top":0.08220271,"width":0.0019946808,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.97539896,"top":0.07821229,"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":"AXTextArea","text":"[2026-05-07 12:34:39] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {\"pid\":32728,\"workerId\":\"\",\"target\":\"activities\"} {\"correlation_id\":\"2dc91923-2a7f-4251-9ddd-5663739b2850\",\"trace_id\":\"2bc19bcd-96d0-45d9-b13c-1c1dba7aff9f\"}\n[2026-05-07 12:35:04] 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\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:04] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:04] 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\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0\",\"trace_id\":\"da1dcdd2-a656-4e5e-8a4b-c714d1175381\"}\n[2026-05-07 12:35:06] 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\":\"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0\",\"trace_id\":\"da1dcdd2-a656-4e5e-8a4b-c714d1175381\"}\n[2026-05-07 12:35:08] local.NOTICE: Monitoring start {\"correlation_id\":\"cc05b2e5-39a2-4fb1-8859-871c3d987279\",\"trace_id\":\"168cc802-ec5c-4bfd-bfa8-45571e2946cc\"}\n[2026-05-07 12:35:08] local.NOTICE: Monitoring end {\"correlation_id\":\"cc05b2e5-39a2-4fb1-8859-871c3d987279\",\"trace_id\":\"168cc802-ec5c-4bfd-bfa8-45571e2946cc\"}\n[2026-05-07 12:35: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\":\"8fdc327b-c3dd-4eed-b9a9-00cc263ed461\",\"trace_id\":\"2b164538-6384-413e-a68b-589aabda4af3\"}\n[2026-05-07 12:35: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\":\"8fdc327b-c3dd-4eed-b9a9-00cc263ed461\",\"trace_id\":\"2b164538-6384-413e-a68b-589aabda4af3\"}\n[2026-05-07 12:35: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\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35: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\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ef495688-effa-4ee7-9b81-ccb161f7c3bf\",\"trace_id\":\"26eabbbc-6174-434e-9756-1b84825f03ab\"}\n[2026-05-07 12:35:14] 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\":\"ef495688-effa-4ee7-9b81-ccb161f7c3bf\",\"trace_id\":\"26eabbbc-6174-434e-9756-1b84825f03ab\"}\n[2026-05-07 12:35:16] 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\":\"aac3580d-654c-4490-ab7d-7d91ff1ce423\",\"trace_id\":\"c35dd663-0ae1-4d03-b56d-120bf7292ecb\"}\n[2026-05-07 12:35:16] 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\":\"aac3580d-654c-4490-ab7d-7d91ff1ce423\",\"trace_id\":\"c35dd663-0ae1-4d03-b56d-120bf7292ecb\"}\n[2026-05-07 12:35:18] 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\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:18] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:18] 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\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] 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\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:30\",\"to\":\"12:35\"} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:25\",\"to\":\"02:30\"} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] 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\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:31] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35: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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] 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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35: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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"de4aa643-9d23-4d24-8c6a-ba951496144e\",\"trace_id\":\"169c2fe6-d32d-45e5-9682-6ae91ce0396f\"}\n[2026-05-07 12:35:36] 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\":\"e37299b2-0176-4eac-815f-0caabf7af320\",\"trace_id\":\"c47be302-8931-4988-a55d-3560a61143b6\"}\n[2026-05-07 12:35:36] 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\":\"de4aa643-9d23-4d24-8c6a-ba951496144e\",\"trace_id\":\"169c2fe6-d32d-45e5-9682-6ae91ce0396f\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:37:36.789343Z\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] 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\":\"e37299b2-0176-4eac-815f-0caabf7af320\",\"trace_id\":\"c47be302-8931-4988-a55d-3560a61143b6\"}\n[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36: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\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36: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\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0ef13206-7c40-464d-a0af-bbaa723080ff\",\"trace_id\":\"fdc7e389-cf4c-4c13-a27d-199959e4691f\"}\n[2026-05-07 12:36: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\":\"0ef13206-7c40-464d-a0af-bbaa723080ff\",\"trace_id\":\"fdc7e389-cf4c-4c13-a27d-199959e4691f\"}\n[2026-05-07 12:36:13] local.NOTICE: Monitoring start {\"correlation_id\":\"87589fd8-76e4-41f4-afe5-f442201ab71c\",\"trace_id\":\"ad59c3de-6d0c-4487-b721-0dfcba13ba89\"}\n[2026-05-07 12:36:13] local.NOTICE: Monitoring end {\"correlation_id\":\"87589fd8-76e4-41f4-afe5-f442201ab71c\",\"trace_id\":\"ad59c3de-6d0c-4487-b721-0dfcba13ba89\"}","depth":4,"bounds":{"left":0.52859044,"top":0.10454908,"width":0.47140956,"height":0.89545095},"on_screen":true,"value":"[2026-05-07 12:34:39] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {\"pid\":32728,\"workerId\":\"\",\"target\":\"activities\"} {\"correlation_id\":\"2dc91923-2a7f-4251-9ddd-5663739b2850\",\"trace_id\":\"2bc19bcd-96d0-45d9-b13c-1c1dba7aff9f\"}\n[2026-05-07 12:35:04] 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\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:04] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:04] 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\":\"174592ac-ef13-4e4e-bf6c-471037fb39b9\",\"trace_id\":\"01ae22a0-6724-4f95-bcd6-02b23ee9896e\"}\n[2026-05-07 12:35:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0\",\"trace_id\":\"da1dcdd2-a656-4e5e-8a4b-c714d1175381\"}\n[2026-05-07 12:35:06] 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\":\"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0\",\"trace_id\":\"da1dcdd2-a656-4e5e-8a4b-c714d1175381\"}\n[2026-05-07 12:35:08] local.NOTICE: Monitoring start {\"correlation_id\":\"cc05b2e5-39a2-4fb1-8859-871c3d987279\",\"trace_id\":\"168cc802-ec5c-4bfd-bfa8-45571e2946cc\"}\n[2026-05-07 12:35:08] local.NOTICE: Monitoring end {\"correlation_id\":\"cc05b2e5-39a2-4fb1-8859-871c3d987279\",\"trace_id\":\"168cc802-ec5c-4bfd-bfa8-45571e2946cc\"}\n[2026-05-07 12:35: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\":\"8fdc327b-c3dd-4eed-b9a9-00cc263ed461\",\"trace_id\":\"2b164538-6384-413e-a68b-589aabda4af3\"}\n[2026-05-07 12:35: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\":\"8fdc327b-c3dd-4eed-b9a9-00cc263ed461\",\"trace_id\":\"2b164538-6384-413e-a68b-589aabda4af3\"}\n[2026-05-07 12:35: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\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35: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\":\"2c210df4-febc-4c68-b86e-f5fa6eea2d8e\",\"trace_id\":\"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0\"}\n[2026-05-07 12:35:14] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ef495688-effa-4ee7-9b81-ccb161f7c3bf\",\"trace_id\":\"26eabbbc-6174-434e-9756-1b84825f03ab\"}\n[2026-05-07 12:35:14] 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\":\"ef495688-effa-4ee7-9b81-ccb161f7c3bf\",\"trace_id\":\"26eabbbc-6174-434e-9756-1b84825f03ab\"}\n[2026-05-07 12:35:16] 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\":\"aac3580d-654c-4490-ab7d-7d91ff1ce423\",\"trace_id\":\"c35dd663-0ae1-4d03-b56d-120bf7292ecb\"}\n[2026-05-07 12:35:16] 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\":\"aac3580d-654c-4490-ab7d-7d91ff1ce423\",\"trace_id\":\"c35dd663-0ae1-4d03-b56d-120bf7292ecb\"}\n[2026-05-07 12:35:18] 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\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:18] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:18] 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\":\"4e9986d1-25ed-4e81-868f-e6021368d776\",\"trace_id\":\"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b\"}\n[2026-05-07 12:35:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {\"correlation_id\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:21] 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\":\"c5e93afe-4aba-4f70-8fb0-859ea99739a7\",\"trace_id\":\"9cf12f9e-4128-4f82-ac7d-faaba7eb3228\"}\n[2026-05-07 12:35:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:30\",\"to\":\"12:35\"} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:25\",\"to\":\"02:30\"} {\"correlation_id\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:25] 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\":\"ecd235ab-ce80-4436-9d41-19760ccf43a7\",\"trace_id\":\"b83badb5-9434-41b9-acd6-3ccd099a581c\"}\n[2026-05-07 12:35:31] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35: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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] 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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35: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\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:32] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b04b75c8-edd6-46d5-834b-a276a7fca1c8\",\"trace_id\":\"9e98a255-f6d0-4d37-961a-51f9241c99e4\"}\n[2026-05-07 12:35:36] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"de4aa643-9d23-4d24-8c6a-ba951496144e\",\"trace_id\":\"169c2fe6-d32d-45e5-9682-6ae91ce0396f\"}\n[2026-05-07 12:35:36] 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\":\"e37299b2-0176-4eac-815f-0caabf7af320\",\"trace_id\":\"c47be302-8931-4988-a55d-3560a61143b6\"}\n[2026-05-07 12:35:36] 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\":\"de4aa643-9d23-4d24-8c6a-ba951496144e\",\"trace_id\":\"169c2fe6-d32d-45e5-9682-6ae91ce0396f\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:37:36.789343Z\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:36] 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\":\"e37299b2-0176-4eac-815f-0caabf7af320\",\"trace_id\":\"c47be302-8931-4988-a55d-3560a61143b6\"}\n[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4\",\"trace_id\":\"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02\"}\n[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:35:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"4374f995-b892-49b7-9eaf-d80bcf1eaec2\",\"trace_id\":\"a0f4c391-5090-49ea-8a57-80d06a576d54\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"79eb6ad9-b5e4-435e-95ad-e451fa993e6a\",\"trace_id\":\"929f5d76-3dbd-4a1b-8db3-65234198f9af\"}\n[2026-05-07 12:36: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\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36: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\":\"b6fa3d42-16e4-4eab-b363-13c6cfb7b814\",\"trace_id\":\"590f9853-355e-49a5-ae3b-99a357cb7f43\"}\n[2026-05-07 12:36:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"0ef13206-7c40-464d-a0af-bbaa723080ff\",\"trace_id\":\"fdc7e389-cf4c-4c13-a27d-199959e4691f\"}\n[2026-05-07 12:36: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\":\"0ef13206-7c40-464d-a0af-bbaa723080ff\",\"trace_id\":\"fdc7e389-cf4c-4c13-a27d-199959e4691f\"}\n[2026-05-07 12:36:13] local.NOTICE: Monitoring start {\"correlation_id\":\"87589fd8-76e4-41f4-afe5-f442201ab71c\",\"trace_id\":\"ad59c3de-6d0c-4487-b721-0dfcba13ba89\"}\n[2026-05-07 12:36:13] local.NOTICE: Monitoring end {\"correlation_id\":\"87589fd8-76e4-41f4-afe5-f442201ab71c\",\"trace_id\":\"ad59c3de-6d0c-4487-b721-0dfcba13ba89\"}","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false}]...
|
2183178296581963220
|
-3017012255716168531
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:34:39] local.INFO: [Commands/AsyncUpdateEsEntities] Starting ES update worker {"pid":32728,"workerId":"","target":"activities"} {"correlation_id":"2dc91923-2a7f-4251-9ddd-5663739b2850","trace_id":"2bc19bcd-96d0-45d9-b13c-1c1dba7aff9f"}
[2026-05-07 12:35:04] 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":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:04] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:04] 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":"174592ac-ef13-4e4e-bf6c-471037fb39b9","trace_id":"01ae22a0-6724-4f95-bcd6-02b23ee9896e"}
[2026-05-07 12:35:06] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0","trace_id":"da1dcdd2-a656-4e5e-8a4b-c714d1175381"}
[2026-05-07 12:35:06] 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":"0db30a7b-1da3-4c9e-8c71-21b3bee4b2b0","trace_id":"da1dcdd2-a656-4e5e-8a4b-c714d1175381"}
[2026-05-07 12:35:08] local.NOTICE: Monitoring start {"correlation_id":"cc05b2e5-39a2-4fb1-8859-871c3d987279","trace_id":"168cc802-ec5c-4bfd-bfa8-45571e2946cc"}
[2026-05-07 12:35:08] local.NOTICE: Monitoring end {"correlation_id":"cc05b2e5-39a2-4fb1-8859-871c3d987279","trace_id":"168cc802-ec5c-4bfd-bfa8-45571e2946cc"}
[2026-05-07 12:35: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":"8fdc327b-c3dd-4eed-b9a9-00cc263ed461","trace_id":"2b164538-6384-413e-a68b-589aabda4af3"}
[2026-05-07 12:35: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":"8fdc327b-c3dd-4eed-b9a9-00cc263ed461","trace_id":"2b164538-6384-413e-a68b-589aabda4af3"}
[2026-05-07 12:35: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":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:12] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:12] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35: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":"2c210df4-febc-4c68-b86e-f5fa6eea2d8e","trace_id":"4a47a36e-f456-4b67-bb03-48ce9b2c4ce0"}
[2026-05-07 12:35:14] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"activity:purge-stale","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ef495688-effa-4ee7-9b81-ccb161f7c3bf","trace_id":"26eabbbc-6174-434e-9756-1b84825f03ab"}
[2026-05-07 12:35:14] 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":"ef495688-effa-4ee7-9b81-ccb161f7c3bf","trace_id":"26eabbbc-6174-434e-9756-1b84825f03ab"}
[2026-05-07 12:35:16] 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":"aac3580d-654c-4490-ab7d-7d91ff1ce423","trace_id":"c35dd663-0ae1-4d03-b56d-120bf7292ecb"}
[2026-05-07 12:35:16] 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":"aac3580d-654c-4490-ab7d-7d91ff1ce423","trace_id":"c35dd663-0ae1-4d03-b56d-120bf7292ecb"}
[2026-05-07 12:35:18] 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":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:18] local.INFO: Running pre-meeting notification command {"correlation_id":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:18] 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":"4e9986d1-25ed-4e81-868f-e6021368d776","trace_id":"e3aa7f2f-780a-4150-9c5a-25b0fb35be7b"}
[2026-05-07 12:35:21] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:start","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:25:00, 2026-05-07 12:30:00] {"correlation_id":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:21] 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":"c5e93afe-4aba-4f70-8fb0-859ea99739a7","trace_id":"9cf12f9e-4128-4f82-ac7d-faaba7eb3228"}
[2026-05-07 12:35:25] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:end","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesEnded {"from":"12:30","to":"12:35"} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] local.INFO: conference:monitor:end:Jiminny\Console\Commands\Activities\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {"from":"02:25","to":"02:30"} {"correlation_id":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:25] 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":"ecd235ab-ce80-4436-9d41-19760ccf43a7","trace_id":"b83badb5-9434-41b9-acd6-3ccd099a581c"}
[2026-05-07 12:35:31] local.NOTICE: Repairing HubSpot tokens start {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {"account_id":59,"updated_at":"2025-10-03 09:32:05"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":59,"provider":"hubspot","refreshToken":"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35: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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: Trying to refresh HubSpot token {"account_id":306,"updated_at":"2023-11-27 09:30:03"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":306,"provider":"hubspot","refreshToken":"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] 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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: Trying to refresh HubSpot token {"account_id":1372,"updated_at":"2025-10-02 14:47:06"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1372,"provider":"hubspot","refreshToken":"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4","state":"full-refresh"} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35: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":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:32] local.NOTICE: Repairing HubSpot tokens end {"total":3,"fixed":0,"failed":3} {"correlation_id":"b04b75c8-edd6-46d5-834b-a276a7fca1c8","trace_id":"9e98a255-f6d0-4d37-961a-51f9241c99e4"}
[2026-05-07 12:35:36] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"crm:bullhorn:ping","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"de4aa643-9d23-4d24-8c6a-ba951496144e","trace_id":"169c2fe6-d32d-45e5-9682-6ae91ce0396f"}
[2026-05-07 12:35:36] 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":"e37299b2-0176-4eac-815f-0caabf7af320","trace_id":"c47be302-8931-4988-a55d-3560a61143b6"}
[2026-05-07 12:35:36] 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":"de4aa643-9d23-4d24-8c6a-ba951496144e","trace_id":"169c2fe6-d32d-45e5-9682-6ae91ce0396f"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Command] Starting polling service {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Service starting {"memory_limit":"256M","max_execution_time":"0","initial_memory_mb":62.0} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Acquired polling lock {"expires_at":"2026-05-07T12:37:36.789343Z"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:36] 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":"e37299b2-0176-4eac-815f-0caabf7af320","trace_id":"c47be302-8931-4988-a55d-3560a61143b6"}
[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4","trace_id":"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02"}
[2026-05-07 12:35:36] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4","trace_id":"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02"}
[2026-05-07 12:35:36] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4","trace_id":"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02"}
[2026-05-07 12:35:36] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"2b2b3086-fa50-4bdf-8140-ea21a3e3edc4","trace_id":"7c76b9ca-9e24-4e90-9e5d-0c60119f3b02"}
[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {"expires_in":1800,"cached_for":1500} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:37] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:42] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:47] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"4374f995-b892-49b7-9eaf-d80bcf1eaec2","trace_id":"a0f4c391-5090-49ea-8a57-80d06a576d54"}
[2026-05-07 12:35:58] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"4374f995-b892-49b7-9eaf-d80bcf1eaec2","trace_id":"a0f4c391-5090-49ea-8a57-80d06a576d54"}
[2026-05-07 12:35:58] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"4374f995-b892-49b7-9eaf-d80bcf1eaec2","trace_id":"a0f4c391-5090-49ea-8a57-80d06a576d54"}
[2026-05-07 12:35:58] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"4374f995-b892-49b7-9eaf-d80bcf1eaec2","trace_id":"a0f4c391-5090-49ea-8a57-80d06a576d54"}
[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] Getting offset from database {"offset":"","jiminny_team_id":1} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:36:02] local.INFO: [HubSpot Journal API] Fetching latest journal entry {"url":"https://api.hubapi.com/webhooks/v4/journal/latest"} {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:36:02] local.INFO: [HubSpot Journal Polling] No data {"correlation_id":"79eb6ad9-b5e4-435e-95ad-e451fa993e6a","trace_id":"929f5d76-3dbd-4a1b-8db3-65234198f9af"}
[2026-05-07 12:36: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":"b6fa3d42-16e4-4eab-b363-13c6cfb7b814","trace_id":"590f9853-355e-49a5-ae3b-99a357cb7f43"}
[2026-05-07 12:36:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"b6fa3d42-16e4-4eab-b363-13c6cfb7b814","trace_id":"590f9853-355e-49a5-ae3b-99a357cb7f43"}
[2026-05-07 12:36: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":"b6fa3d42-16e4-4eab-b363-13c6cfb7b814","trace_id":"590f9853-355e-49a5-ae3b-99a357cb7f43"}
[2026-05-07 12:36:09] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"dialers:monitor-activities","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"0ef13206-7c40-464d-a0af-bbaa723080ff","trace_id":"fdc7e389-cf4c-4c13-a27d-199959e4691f"}
[2026-05-07 12:36: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":"0ef13206-7c40-464d-a0af-bbaa723080ff","trace_id":"fdc7e389-cf4c-4c13-a27d-199959e4691f"}
[2026-05-07 12:36:13] local.NOTICE: Monitoring start {"correlation_id":"87589fd8-76e4-41f4-afe5-f442201ab71c","trace_id":"ad59c3de-6d0c-4487-b721-0dfcba13ba89"}
[2026-05-07 12:36:13] local.NOTICE: Monitoring end {"correlation_id":"87589fd8-76e4-41f4-afe5-f442201ab71c","trace_id":"ad59c3de-6d0c-4487-b721-0dfcba13ba89"}...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3694
|
135
|
5
|
2026-05-07T12:36:14.919430+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157374919_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
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need to check if Crm profile - Log Notes field is enabled
// We only check if store_transcript toggle is enabled on crm profile.
$engagement = [
'active' => true,
'ownerId' => $this->profile->crm_provider_id,
'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,
'type' => 'NOTE',
];
// Generate activity transcription.
$transcriptionData = $this->generateTranscription($activity);
// Truncate Notes with max notes length because transcription text could be very long.
$transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);
$metadata = [
'body' => $transcripts,
];
$associations = $this->convertActivityAssociations($activity);
try {
$hsEngagement = $this->client
->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
$this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);
$noteId = $hsEngagement->data->engagement->id;
// Store crm logged id in transcription.
$transcription = $activity->getTranscription();
$transcription->crm_activity_id = $noteId;
$transcription->save();
} catch (Exception $e) {
Sentry::captureException($e);
}
}
/*
* @inheritdoc
*/
public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void
{
$payload = [
'properties' => $data,
];
try {
switch ($objectType) {
case FieldData::OBJECT_OPPORTUNITY:
$this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_CONTACT:
$this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_ACCOUNT:
$this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_TASK:
// Endpoint for Engagements not ready
$engagements = [
'type' => 'TASK',
];
$metadata = $data;
$this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);
$this->logCrmEngagementManipulation(
self::ACTION_UPDATE,
['crmId' => $objectId],
$metadata,
);
break;
default:
throw new UnexpectedValueException('Unsupported object type "' . $objectType . '"');
}
} catch (\HubSpot\Client\Crm\Deals\ApiException $apiException) {
$errorMessage = $apiException->getMessage();
if ($apiException->getResponseBody()) {
$responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);
$errorMessage = $responseBody['message'] ?? $apiException->getMessage();
}
$this->logger->error(
'[HubSpot] Update record failed',
[
'objectType' => $objectType,
'objectId' => $objectI...
|
[{"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":"8","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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}]...
|
5003501518913582683
|
-465335736597342105
|
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
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need to check if Crm profile - Log Notes field is enabled
// We only check if store_transcript toggle is enabled on crm profile.
$engagement = [
'active' => true,
'ownerId' => $this->profile->crm_provider_id,
'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,
'type' => 'NOTE',
];
// Generate activity transcription.
$transcriptionData = $this->generateTranscription($activity);
// Truncate Notes with max notes length because transcription text could be very long.
$transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);
$metadata = [
'body' => $transcripts,
];
$associations = $this->convertActivityAssociations($activity);
try {
$hsEngagement = $this->client
->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
$this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);
$noteId = $hsEngagement->data->engagement->id;
// Store crm logged id in transcription.
$transcription = $activity->getTranscription();
$transcription->crm_activity_id = $noteId;
$transcription->save();
} catch (Exception $e) {
Sentry::captureException($e);
}
}
/*
* @inheritdoc
*/
public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void
{
$payload = [
'properties' => $data,
];
try {
switch ($objectType) {
case FieldData::OBJECT_OPPORTUNITY:
$this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_CONTACT:
$this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_ACCOUNT:
$this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_TASK:
// Endpoint for Engagements not ready
$engagements = [
'type' => 'TASK',
];
$metadata = $data;
$this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);
$this->logCrmEngagementManipulation(
self::ACTION_UPDATE,
['crmId' => $objectId],
$metadata,
);
break;
default:
throw new UnexpectedValueException('Unsupported object type "' . $objectType . '"');
}
} catch (\HubSpot\Client\Crm\Deals\ApiException $apiException) {
$errorMessage = $apiException->getMessage();
if ($apiException->getResponseBody()) {
$responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);
$errorMessage = $responseBody['message'] ?? $apiException->getMessage();
}
$this->logger->error(
'[HubSpot] Update record failed',
[
'objectType' => $objectType,
'objectId' => $objectI...
|
3690
|
NULL
|
NULL
|
NULL
|
|
3693
|
136
|
7
|
2026-05-07T12:36:14.839244+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157374839_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
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need to check if Crm profile - Log Notes field is enabled
// We only check if store_transcript toggle is enabled on crm profile.
$engagement = [
'active' => true,
'ownerId' => $this->profile->crm_provider_id,
'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,
'type' => 'NOTE',
];
// Generate activity transcription.
$transcriptionData = $this->generateTranscription($activity);
// Truncate Notes with max notes length because transcription text could be very long.
$transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);
$metadata = [
'body' => $transcripts,
];
$associations = $this->convertActivityAssociations($activity);
try {
$hsEngagement = $this->client
->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
$this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);
$noteId = $hsEngagement->data->engagement->id;
// Store crm logged id in transcription.
$transcription = $activity->getTranscription();
$transcription->crm_activity_id = $noteId;
$transcription->save();
} catch (Exception $e) {
Sentry::captureException($e);
}
}
/*
* @inheritdoc
*/
public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void
{
$payload = [
'properties' => $data,
];
try {
switch ($objectType) {
case FieldData::OBJECT_OPPORTUNITY:
$this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_CONTACT:
$this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_ACCOUNT:
$this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_TASK:
// Endpoint for Engagements not ready
$engagements = [
'type' => 'TASK',
];
$metadata = $data;
$this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);
$this->logCrmEngagementManipulation(
self::ACTION_UPDATE,
['crmId' => $objectId],
$metadata,
);
break;
default:
throw new UnexpectedValueException('Unsupported object type "' . $objectType . '"');
}
} catch (\HubSpot\Client\Crm\Deals\ApiException $apiException) {
$errorMessage = $apiException->getMessage();
if ($apiException->getResponseBody()) {
$responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);
$errorMessage = $responseBody['message'] ?? $apiException->getMessage();
}
$this->logger->error(
'[HubSpot] Update record failed',
[
'objectType' => $objectType,
'objectId' => $objectI...
|
[{"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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"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":"8","depth":4,"bounds":{"left":0.46176863,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"bounds":{"left":0.47174203,"top":0.19952115,"width":0.009640957,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.48337767,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","depth":4,"bounds":{"left":0.49268618,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.5049867,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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}]...
|
5003501518913582683
|
-465335736597342105
|
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
8
51
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need to check if Crm profile - Log Notes field is enabled
// We only check if store_transcript toggle is enabled on crm profile.
$engagement = [
'active' => true,
'ownerId' => $this->profile->crm_provider_id,
'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,
'type' => 'NOTE',
];
// Generate activity transcription.
$transcriptionData = $this->generateTranscription($activity);
// Truncate Notes with max notes length because transcription text could be very long.
$transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);
$metadata = [
'body' => $transcripts,
];
$associations = $this->convertActivityAssociations($activity);
try {
$hsEngagement = $this->client
->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
$this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);
$noteId = $hsEngagement->data->engagement->id;
// Store crm logged id in transcription.
$transcription = $activity->getTranscription();
$transcription->crm_activity_id = $noteId;
$transcription->save();
} catch (Exception $e) {
Sentry::captureException($e);
}
}
/*
* @inheritdoc
*/
public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void
{
$payload = [
'properties' => $data,
];
try {
switch ($objectType) {
case FieldData::OBJECT_OPPORTUNITY:
$this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_CONTACT:
$this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_ACCOUNT:
$this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_TASK:
// Endpoint for Engagements not ready
$engagements = [
'type' => 'TASK',
];
$metadata = $data;
$this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);
$this->logCrmEngagementManipulation(
self::ACTION_UPDATE,
['crmId' => $objectId],
$metadata,
);
break;
default:
throw new UnexpectedValueException('Unsupported object type "' . $objectType . '"');
}
} catch (\HubSpot\Client\Crm\Deals\ApiException $apiException) {
$errorMessage = $apiException->getMessage();
if ($apiException->getResponseBody()) {
$responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);
$errorMessage = $responseBody['message'] ?? $apiException->getMessage();
}
$this->logger->error(
'[HubSpot] Update record failed',
[
'objectType' => $objectType,
'objectId' => $objectI...
|
3692
|
NULL
|
NULL
|
NULL
|
|
3692
|
136
|
6
|
2026-05-07T12:36:11.186483+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157371186_m2.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/Service.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
8
48
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need to check if Crm profile - Log Notes field is enabled
// We only check if store_transcript toggle is enabled on crm profile.
$engagement = [
'active' => true,
'ownerId' => $this->profile->crm_provider_id,
'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,
'type' => 'NOTE',
];
// Generate activity transcription.
$transcriptionData = $this->generateTranscription($activity);
// Truncate Notes with max notes length because transcription text could be very long.
$transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);
$metadata = [
'body' => $transcripts,
];
$associations = $this->convertActivityAssociations($activity);
try {
$hsEngagement = $this->client
->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
$this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);
$noteId = $hsEngagement->data->engagement->id;
// Store crm logged id in transcription.
$transcription = $activity->getTranscription();
$transcription->crm_activity_id = $noteId;
$transcription->save();
} catch (Exception $e) {
Sentry::captureException($e);
}
}
/*
* @inheritdoc
*/
public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void
{
$payload = [
'properties' => $data,
];
try {
switch ($objectType) {
case FieldData::OBJECT_OPPORTUNITY:
$this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_CONTACT:
$this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_ACCOUNT:
$this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_TASK:
// Endpoint for Engagements not ready
$engagements = [
'type' => 'TASK',
];
$metadata = $data;
$this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);
$this->logCrmEngagementManipulation(
self::ACTION_UPDATE,
['crmId' => $objectId],
$metadata,
);
break;
default:
throw new UnexpectedValueException('Unsupported object type "' . $objectType . '"');
}
} catch (\HubSpot\Client\Crm\Deals\ApiException $apiException) {
$errorMessage = $apiException->getMessage();
if ($apiException->getResponseBody()) {
$responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);
$errorMessage = $responseBody['message'] ?? $apiException->getMessage();
}
$this->logger->error(
'[HubSpot] Update record failed',
[
'objectType' => $objectType,
'objectId' => $objectI...
|
[{"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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"on_screen":true,"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":"8","depth":4,"bounds":{"left":0.46110374,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"48","depth":4,"bounds":{"left":0.4710771,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.48337767,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","depth":4,"bounds":{"left":0.49268618,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.5049867,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n return null;\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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}]...
|
-2089932637180310473
|
-465335736597342105
|
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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
8
48
1
33
1
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Services\Crm\Hubspot;
use Carbon\Carbon;
use Exception;
use Generator;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Support\Facades\Cache;
use InvalidArgumentException;
use Jiminny\Contracts\Repositories\TeamRepository;
use Jiminny\Contracts\Services\Crm\ClientInterface;
use Jiminny\Contracts\Services\Crm\FetchRelatedActivityInterface;
use Jiminny\Contracts\Services\Crm\LayoutManagementInterface;
use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\Provider\HubspotInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityLookupInterface;
use Jiminny\Contracts\Services\Crm\RemoteEntityManipulationInterface;
use Jiminny\Contracts\Services\Crm\SavePlaybackLinkToCrmInterface;
use Jiminny\Contracts\Services\Crm\SendSummaryToCrmInterface;
use Jiminny\Contracts\Services\Crm\SettingsInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmEntitiesInterface;
use Jiminny\Contracts\Services\Crm\SyncCrmMetadataInterface;
use Jiminny\Contracts\Services\Crm\VerifyTaskExistsInterface;
use Jiminny\Exceptions\CrmException;
use Jiminny\Exceptions\HttpNotFoundException;
use Jiminny\Jobs\Crm\NoteObject;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Contact;
use Jiminny\Models\Contracts\ActivityContract;
use Jiminny\Models\Crm\BusinessProcess;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\Profile;
use Jiminny\Models\Lead;
use Jiminny\Models\Opportunity;
use Jiminny\Models\Participant;
use Jiminny\Models\Playbook;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Stage;
use Jiminny\Models\User;
use Jiminny\Repositories\Crm\CrmEntityRepository;
use Jiminny\Repositories\Crm\FieldRepository;
use Jiminny\Repositories\Crm\ProfileRepository;
use Jiminny\Repositories\ParticipantRepository;
use Jiminny\Services\Avatar\ProspectPhotoPathService;
use Jiminny\Services\Crm\BaseService;
use Jiminny\Services\Crm\Hubspot\Actions\SyncArchivedProfilesAction;
use Jiminny\Services\Crm\Hubspot\Fields\ValueNormalizer;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\OpportunitySyncTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncCrmEntitiesTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\SyncFieldsTrait;
use Jiminny\Services\Crm\Hubspot\ServiceTraits\WriteCrmTrait;
use Jiminny\Services\Crm\MatchDomainByEmailInterface;
use Jiminny\Services\Crm\OpportunitySyncStrategyResolver;
use Jiminny\Services\Crm\ResolveCompanyNameByEmailTrait;
use Jiminny\Utils\PlaybackUrlBuilder;
use Sentry;
use SevenShores\Hubspot\Exceptions\BadRequest;
use Throwable;
use UnexpectedValueException;
/**
* @phpstan-type CrmFieldDefinition array{
* name: string,
* label: string,
* description: string,
* type: string,
* fieldType: string,
* hidden: bool,
* showCurrencySymbol: bool,
* options: array<array{
* id: string,
* label: string,
* value?: string,
* }
*/
class Service extends BaseService implements
HubspotInterface,
SyncCrmEntitiesInterface,
SyncCrmMetadataInterface,
SendSummaryToCrmInterface,
MatchDomainByEmailInterface,
SavePlaybackLinkToCrmInterface,
RemoteEntityManipulationInterface,
FetchRelatedActivityInterface,
LayoutManagementInterface,
SettingsInterface,
MatchCrmEntitiesInterface,
RemoteEntityLookupInterface,
VerifyTaskExistsInterface
{
use ResolveCompanyNameByEmailTrait;
use SyncCrmEntitiesTrait;
use WriteCrmTrait;
use SyncFieldsTrait;
use OpportunitySyncTrait;
private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;
private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';
private const int BATCH_UPDATE_LIMIT = 100;
private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';
private const int TEN_SECONDLY_ROLLING_LIMIT = 10;
private const string CALLS_SEARCH_ENDPOINT = '[URL_WITH_CREDENTIALS] ClientInterface|Client
*/
protected $client;
protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;
protected CrmEntityRepository $crmEntityRepository;
protected ProspectPhotoPathService $prospectPhotoPathService;
private SyncFieldAction $syncFieldAction;
private PayloadBuilder $payloadBuilder;
private SyncRelatedActivityManager $syncRelatedActivityManager;
private SyncArchivedProfilesAction $syncArchivedProfilesAction;
private WebhookSyncBatchProcessor $batchProcessor;
public function __construct(
Client $client,
SyncFieldAction $syncFieldAction,
PayloadBuilder $payloadBuilder,
ProspectPhotoPathService $prospectPhotoPathService,
SyncArchivedProfilesAction $syncArchivedProfilesAction,
WebhookSyncBatchProcessor $batchProcessor,
) {
parent::__construct();
$this->client = $client;
$this->syncFieldAction = $syncFieldAction;
$this->prospectPhotoPathService = $prospectPhotoPathService;
$this->payloadBuilder = $payloadBuilder;
$this->syncArchivedProfilesAction = $syncArchivedProfilesAction;
$this->batchProcessor = $batchProcessor;
$this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [
'client' => $this->client,
]);
$this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [
'client' => $this->client,
'payloadBuilder' => $this->payloadBuilder,
'logger' => $this->logger,
]);
$this->crmEntityRepository = app(CrmEntityRepository::class);
$this->dealFieldsService = app(DealFieldsService::class);
}
public function getDisplayName(): string
{
return 'HubSpot';
}
protected function getOAuthAccount(User $user): ?SocialAccount
{
// In this case, the Account Owner is always the connection for any API operations.
$owner = $user->team->owner;
return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);
}
public function getClient(): Client
{
/** @var Client */
return $this->client;
}
/**
* Convert raw field data into a format compatible with CRM APIs.
*
* @param bool $internal Direction of the conversion.
* True is pulling from CRM, false normalize before sending to CRM.
*/
public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string
{
return ValueNormalizer::normalize(
fieldType: $fieldType,
fieldValue: $fieldValue,
isInbound: $internal,
);
}
/**
* @inheritdoc
*/
public function getDefaultFields(string $activityType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
$defaultFields = FieldDefinitions::defaultTaskFields();
// This lazy creates these fields if not already setup.
foreach ($defaultFields as $defaultField) {
$fields[] = $this->config->fields()->firstOrCreate($defaultField);
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function getDefaultActivityField(string $activityType): Field
{
/** @var Field $activityField */
$activityField = $this->config->fields()->where([
'crm_provider_id' => 'activityType',
'object_type' => $activityType,
])->first();
return $activityField;
}
/**
* @inheritdoc
*/
public function getSupportedPlaybookTypes(): array
{
return [Playbook::ACTIVITY_TYPE_TASK];
}
/**
* @inheritdoc
*/
public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array
{
$fields = [];
if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {
// Outcome should always be provided calls/meetings.
$fieldData = [
[
'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',
'object_type' => Field::OBJECT_TASK,
],
];
foreach ($fieldData as $data) {
$field = $this->config->fields()->where($data)->first();
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
}
return $fields;
}
public function getDealInsightsFields(): array
{
return FieldDefinitions::dealInsightsFields();
}
protected function getDefaultFollowupLayoutFields(string $activityType): array
{
$fields = [];
$fieldRepo = app(FieldRepository::class);
$fieldData = FieldDefinitions::followupFieldsFilter();
foreach ($fieldData as $data) {
$field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);
// Only add the field if it is created, which it should be.
if ($field) {
$fields[] = $field;
}
}
return $fields;
}
/**
* @inheritdoc
*/
public function syncField(Field $field): void
{
switch ($field->object_type) {
case Field::OBJECT_ACCOUNT:
$crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_CONTACT:
$crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_OPPORTUNITY:
$crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);
break;
case Field::OBJECT_TASK:
$this->syncSingleTaskField($field);
return;
default:
return;
}
$this->syncFieldAction->execute($field, $crmField->toArray());
}
/**
* @param array<array{
* id:string,
* label:string,
* value?:string
* }> $options
*
* @throws CrmException
*
* @return FieldData[]
*
*/
public function importPicklistValues(
Field $field,
array $options = [['id' => '', 'label' => '', 'value' => '']],
): array {
if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {
// We already have the options, no need to fetch them again
return $this->importOptions($field, $options);
}
$options = [];
switch ($field->getObjectType()) {
case Field::OBJECT_ACCOUNT:
$options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());
break;
case Field::OBJECT_CONTACT:
$options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());
break;
case Field::OBJECT_OPPORTUNITY:
// Hubspot has different endpoint for stages
$options = $this->getClient()->fetchOpportunityFieldOptions($field);
break;
case Field::OBJECT_TASK:
if ($field->getCrmProviderId() === 'disposition') {
$options = $this->getClient()->fetchDispositionFieldOptions();
} elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {
$options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);
}
break;
default:
$this->logger->warning('Invalid object type', [
'object_type' => $field->getObjectType(),
'field_id' => $field->getId(),
]);
throw new CrmException('Invalid object type');
}
return $this->importOptions($field, $options);
}
/**
* @inheritdoc
*/
public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage
{
$missingStage = null;
try {
// Use the HubSpot API client instead of the SDK crmPipelines() method
$endpoint = self::getDealsPipelinesEndpoint();
$pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);
$pipelines = $pipelinesResponse->data->results;
} catch (RequestException|BadRequest $exception) {
throw $exception;
}
foreach ($pipelines as $pipeline) {
$stages = [];
// We create a business process to contain the pipeline, and store all stages against it.
$p = ResponseNormalize::normalizePipeline($pipeline);
// Create/update business process for this pipeline
$businessProcess = $this->config->businessProcesses()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'type' => BusinessProcess::TYPE_OPPORTUNITY,
'is_selectable' => $p['active'],
]);
// A record type is really a clone of the business process, used to store which record uses which pipeline.
// Create/update record type clone
$this->config->recordTypes()->updateOrCreate([
'crm_provider_id' => $p['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($p['label'], 0, 150),
'is_selectable' => $p['active'],
'business_process_id' => $businessProcess->id ?? null,
]);
// Stages - fetch all existing stages upfront to avoid N+1 queries
$existingStages = $this->config->stages()
->withTrashed()
->where('type', Stage::TYPE_OPPORTUNITY)
->get()
->keyBy('crm_provider_id');
foreach ($p['stages'] as $dealStage) {
$s = ResponseNormalize::normalizeDealStage($dealStage);
/** @var ?Stage $existingStage */
$existingStage = $existingStages->get($s['id']);
// Restore soft-deleted stages that are now active in HubSpot
if ($existingStage?->trashed() && $s['active']) {
$existingStage->restore();
}
// Upsert stage (updates soft-deleted records without restoring them)
$stage = $this->config->stages()->withTrashed()->updateOrCreate([
'crm_provider_id' => $s['id'],
], [
'team_id' => $this->team->id,
'name' => mb_strimwidth($s['label'], 0, 50),
'label' => mb_strimwidth($s['label'], 0, 191),
'type' => Stage::TYPE_OPPORTUNITY,
'sequence' => $s['displayOrder'],
'is_selectable' => $s['active'],
'probability' => $s['probability'] * 100,
]);
if ($missingStageName === $s['id']) {
$missingStage = $stage;
}
$stages[] = $stage->id;
}
$businessProcess->stages()->sync($stages);
}
return $missingStage;
}
/**
* @inheritdoc
*/
public function syncOrganization(): void
{
try {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function find(string $name, array $scopes): array
{
$count = $this->limit ?? 20;
$offset = $this->offset ?? 0;
/** @var array<int, array<string, mixed>> */
return Cache::remember(
key: $this->team->getId() . $name . $count . $offset,
ttl: 300,
callback: function () use ($name, $offset, $count): array {
$data = [];
// Use the new V3 API to find contacts based on additional fields.
foreach (['companies', 'contacts'] as $objectType) {
$endpoint = '[URL_WITH_CREDENTIALS]
*/
public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array
{
$data = [];
$ownerData = [];
$ownerId = null;
if ($crmAccountId === null) {
return $data;
}
if ($userId) {
$profileRepository = app(ProfileRepository::class);
$profile = $profileRepository->findProfileByUserId($this->config, $userId);
$ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;
}
$closedStages = $this->getClosedDealStages();
$payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(
$this->config,
$crmAccountId,
$closedStages,
);
$results = $this->client->getPaginatedData($payload, 'deals');
foreach ($results['results'] as $object) {
$properties = $object['properties'];
$amount = null;
if (empty($properties['amount']) === false) {
$currency = $properties['deal_currency_code'] ?? $this->config->default_currency;
// Values can contain commas and any junk so strip them.
$value = (float) preg_replace('/[^\d.]/', '', $properties['amount']);
$amount = formatCurrency($value, $currency);
}
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
if ($businessProcess === null) {
// Import it.
$stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);
$businessProcess = $this->config
->businessProcesses()
->where('crm_provider_id', $properties['pipeline'])
->first();
} else {
$stage = $businessProcess
->stages()
->where('crm_provider_id', $properties['dealstage'])
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
if ($stage === null) {
// Import it.
$stage = $this->importStages(null, $properties['dealstage']);
}
}
$recordType = null;
if ($businessProcess) {
$recordType = $businessProcess->recordTypes()->first();
}
$isWon = in_array($properties['dealstage'], $closedStages['won']);
$isLost = in_array($properties['dealstage'], $closedStages['lost']);
$record = [
'crmId' => $object['id'],
'name' => $properties['dealname'] ?? 'Unknown Deal',
'value' => $amount,
'won' => $isWon,
'closed' => $isWon || $isLost,
'stage' => [
'id' => $stage?->getUuid() ?? '',
'name' => $stage?->getName() ?? '',
],
];
if ($recordType) {
$record += [
'recordType' => [
'id' => $recordType->id_string,
'name' => $recordType->name,
],
];
}
if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {
$ownerData[] = $record;
}
$data[] = $record;
}
if (! empty($ownerData)) {
return $ownerData;
}
return $data;
}
/**
* @inheritdoc
*/
public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array
{
$data = [];
switch ($objectType) {
case 'contact':
$hsObject = 'contact';
break;
case 'account':
$hsObject = 'company';
break;
default:
// This is a hack to prioritise and override a contact/company with a deal.
if ($opportunityId) {
$hsObject = 'deal';
$objectId = $opportunityId;
} else {
throw new InvalidArgumentException('Object type not supported.');
}
}
$engagementTypes = ['meetings', 'tasks'];
foreach ($engagementTypes as $engagementType) {
$payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);
$this->logger->info('[HubSpot] CRM Search requested', [
'request' => $payload,
]);
$engagements = $this->client->getPaginatedData($payload, $engagementType);
foreach ($engagements['results'] as $engagement) {
if ($engagementType == 'meetings') {
$title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';
} elseif ($engagementType == 'tasks') {
$title = $engagement['properties']['hs_task_subject'];
} else {
$title = 'Scheduled meeting';
}
$data[] = [
'crmId' => $engagement['id'],
'subject' => $title,
'due' => $engagement['properties']['hs_timestamp'],
'type' => $engagement['properties']['hs_activity_type'] ?? null,
];
}
}
usort($data, function ($item1, $item2) {
return $item2['due'] <=> $item1['due'];
});
return $data;
}
/**
* Try to find CRM Objects using email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchExactlyByEmail(string $email, ?int $userId = null): ?array
{
$contactProperties = [
'email',
// 'firstname',
// 'lastname',
// 'country',
// 'phone',
// 'mobilephone',
// 'jobtitle',
// 'hubspot_owner_id',
// 'associatedcompanyid',
// 'photo',
];
$contact = null;
$account = null;
try {
$hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);
return null;
if ($hsContact) {
$contact = $this->importContact($hsContact);
$account = $contact->account;
}
$data = $this->convertCrmData($contact, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
} catch (BadRequest $e) {
$this->logger->warning('[HubSpot] Search failed', [
'team_id' => $this->team->getId(),
'search_identifier' => $email,
'reason' => $e->getMessage(),
]);
}
return null;
}
public function getDomain(string $email): ?string
{
return $this->getDomainFromEmail($email);
}
/**
* Try to find CRM objects using domain name of the email address
*
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByDomain(string $domain, ?int $userId = null): ?array
{
$companyName = $domain;
// Try to find a company matching their email domain.
$companyProperties = [
'country',
'phone',
'name',
'hs_avatar_filemanager_key',
'industry',
'hubspot_owner_id',
'domain',
];
try {
$hsAccounts = $this->client
->getInstance()
->companies()
->searchByDomain($companyName, $companyProperties);
} catch (Throwable $e) {
$this->logger->info('[HubSpot] Search failed', [
'error' => $e->getMessage(),
'domain' => $domain,
]);
return null;
}
$account = null;
// If there are multiple accounts, don't guess, we'll ask later.
if (\count($hsAccounts->data->results) === 1) {
// Persist this remote object.
$account = $this->syncAccount($hsAccounts->data->results[0]->companyId);
}
$data = $this->convertCrmData(null, $account, $userId);
return ! empty(array_filter($data)) ? $data : null;
}
/**
* @return array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array
{
$countryCode = null;
if ($contact && $contact->country_code) {
$countryCode = $contact->country_code;
} elseif ($account && $account->country_code) {
$countryCode = $account->country_code;
}
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact ? $contact->crm_provider_id : null,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
// If there are multiple opportunities, don't guess, we'll ask later.
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
protected function getCacheKey(string $object, ?int $userId = null): ?string
{
$key = $this->team->getId() . $object;
$keySuffix = $this->getOwnerKeySuffix($userId);
return $key . $keySuffix;
}
private function getOwnerKeySuffix(?int $userId = null): string
{
return $userId === null ? '' : (string) $userId;
}
/**
* @return null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
*}
*/
public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array
{
if (str_contains($phone, '**')) {
return null;
}
// trim all whitespaces if present so the lookup doesn't fail
$phone = str_replace(' ', '', $phone);
// Check if the user is internal.
if ($this->isPhoneNumberOfTeamMember($phone)) {
return null;
}
$response = $this->searchForPhoneNumber($phone);
if (empty($response)) {
return null;
}
// This would ideally importContact instead but the response type differs.
$contact = $this->findAndSyncContact($response['results'][0]['id']);
if (! $contact instanceof Contact) {
return null;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account?->crm_provider_id,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
try {
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
} catch (Exception $e) {
$this->logger->debug('[HubSpot] Opportunity failed to sync.', [
'reason' => $e->getMessage(),
]);
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
}
private function isPhoneNumberOfTeamMember(string $phone): bool
{
$teamRepository = app(TeamRepository::class);
$user = $teamRepository->findTeamMemberByPhone($this->team, $phone);
if ($user instanceof User) {
return true;
}
return false;
}
private function findAndSyncContact(string $crmId): ?Contact
{
try {
return $this->syncContact($crmId);
} catch (Exception $exception) {
$this->logger->info('[HubSpot] Phone match failed', [
'reason' => $exception->getMessage(),
]);
return null;
}
}
private function hasResults(array $response): bool
{
return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;
}
private function searchForPhoneNumber(string $phone): array
{
// Normalizes the provided phone number for the API search.
$normalizedPhone = $this->normalizePhoneNumber($phone);
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);
$this->logger->info('[HubSpot] Phone match search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);
if (! $this->hasResults($response)) {
$nationalPhone = preg_replace('/\D/', '', phone_national(null, $phone));
$payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);
$this->logger->info('[HubSpot] Phone match national number search triggered', [
'phone' => $phone,
'nationalPhone' => $nationalPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
if (! $this->hasResults($response)) {
$payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);
$this->logger->info('[HubSpot] Phone match alternative search triggered', [
'phone' => $phone,
'normalizedPhone' => $normalizedPhone,
'payload' => $payload,
]);
$response = $this->handlePhoneSearchRequest($phone, $payload);
}
return $this->hasResults($response) ? $response : [];
}
private function handlePhoneSearchRequest(string $phone, array $payload): array
{
$endpoint = '[URL_WITH_CREDENTIALS] null|array{
* Lead|null,
* Account|null,
* Opportunity|null,
* Contact|null,
* Stage|null,
* string|null
* }
*/
public function matchByName(string $name, ?int $userId = null): ?array
{
// Don't waste time searching for single character strings.
if (\strlen($name) <= 1) {
return null;
}
$cacheKey = $this->getCacheKey($name, $userId);
$result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {
$payload = $this->payloadBuilder->generateSearchContactsByNamePayload(
$name,
$this->getContactFields()
);
$hsContacts = $this->client->getPaginatedData($payload, 'contact');
if (empty($hsContacts['results'])) {
return false;
}
$contact = $this->importContact($hsContacts['results'][0]);
if ($contact === null) {
return false;
}
$account = $contact->account;
$countryCode = $contact->country_code ?? $account->country_code ?? null;
try {
$hsOpportunities = $this->findOpportunities(
$account ? $account->crm_provider_id : null,
$contact->crm_provider_id,
$userId
);
} catch (Exception $e) {
$hsOpportunities = [];
}
$opportunity = null;
$stage = null;
if (! empty($hsOpportunities)) {
// Persist this remote object.
$opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);
$stage = $opportunity?->getStage();
}
return [
null,
$account,
$opportunity,
$contact,
$stage,
$countryCode,
];
});
return is_array($result) ? $result : null;
}
private function convertActivityAssociations(Activity $activity): array
{
return [
'contactIds' => $this->getParticipantsIds($activity),
'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],
'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],
'ownerIds' => [],
];
}
private function getParticipantsIds(Activity $activity): array
{
$attendees = [];
$participantRepository = app(ParticipantRepository::class);
$participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);
foreach ($participants as $participant) {
if ($participant->user_id || $participant->isCoach()) {
continue;
}
$contact = $participant->contact()->first();
if ($contact && $contact->crm_provider_id) {
$attendees[] = $contact->crm_provider_id;
} else {
if (! empty($participant->name)) {
$attendeeData = $this->fetchMissingAttendeeInfo($participant);
}
if (! empty($attendeeData['id'])) {
$attendees[] = $attendeeData['id'];
}
}
}
if ($activity->hasContact()) {
$attendees[] = $activity->contact->crm_provider_id;
}
return array_unique($attendees);
}
private function fetchMissingAttendeeInfo(Participant $participant): array
{
// Check if we need to look inside an account context.
$activity = $participant->getActivity();
$companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;
// First check the local data.
/** @var Contact[] $contacts */
$contacts = $this->team->contacts()
->with('account')
->where('name', $participant->name)
->whereNotNull('email')
->get();
foreach ($contacts as $contact) {
// If we have a company in scope, check the contact is associated to it.
if (
$companyId !== null
&& ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)
) {
continue;
}
return [
'id' => $contact->crm_provider_id,
'email' => $contact->email,
];
}
$payload = $this->generateNameSearchPayload($participant->name, 0, 20);
try {
$response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);
// TODO add some logic to choose the most suitable contact if multiple
foreach ($response['results'] as $object) {
$properties = $object['properties'];
if (empty($object['properties']) === false) {
// Check the company matches the contact.
// Todo: Move this check inside the API search.
if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {
continue;
}
return [
'id' => $object['id'],
'email' => $properties['email'],
];
}
}
} catch (Exception $e) {
$this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [
'teamId' => $this->team->id_string,
'request' => $payload,
'reason' => $e->getMessage(),
]);
}
return [];
}
/**
* Store transcripts as note engagement.
*
* @throws Exception
*/
public function createTranscriptNotes(Activity $activity): void
{
// For HS no need to check if Crm profile - Log Notes field is enabled
// We only check if store_transcript toggle is enabled on crm profile.
$engagement = [
'active' => true,
'ownerId' => $this->profile->crm_provider_id,
'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,
'type' => 'NOTE',
];
// Generate activity transcription.
$transcriptionData = $this->generateTranscription($activity);
// Truncate Notes with max notes length because transcription text could be very long.
$transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);
$metadata = [
'body' => $transcripts,
];
$associations = $this->convertActivityAssociations($activity);
try {
$hsEngagement = $this->client
->getInstance()
->engagements()
->create($engagement, $associations, $metadata);
$this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);
$noteId = $hsEngagement->data->engagement->id;
// Store crm logged id in transcription.
$transcription = $activity->getTranscription();
$transcription->crm_activity_id = $noteId;
$transcription->save();
} catch (Exception $e) {
Sentry::captureException($e);
}
}
/*
* @inheritdoc
*/
public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void
{
$payload = [
'properties' => $data,
];
try {
switch ($objectType) {
case FieldData::OBJECT_OPPORTUNITY:
$this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_CONTACT:
$this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_ACCOUNT:
$this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);
break;
case FieldData::OBJECT_TASK:
// Endpoint for Engagements not ready
$engagements = [
'type' => 'TASK',
];
$metadata = $data;
$this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);
$this->logCrmEngagementManipulation(
self::ACTION_UPDATE,
['crmId' => $objectId],
$metadata,
);
break;
default:
throw new UnexpectedValueException('Unsupported object type "' . $objectType . '"');
}
} catch (\HubSpot\Client\Crm\Deals\ApiException $apiException) {
$errorMessage = $apiException->getMessage();
if ($apiException->getResponseBody()) {
$responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);
$errorMessage = $responseBody['message'] ?? $apiException->getMessage();
}
$this->logger->error(
'[HubSpot] Update record failed',
[
'objectType' => $objectType,
'objectId' => $objectI...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3691
|
136
|
5
|
2026-05-07T12:36:08.102447+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157368102_m2.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/Service.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormINavigarecodeLaravelKeractorJOOISWindowFV PhpStormINavigarecodeLaravelKeractorJOOISWindowFV faVsco.js°9 master kProiectRateLimitException.php© SyncToUserPilot.phpC) RateLimitAwareWrapper.pnpC. IterateUserscommand.on© JiminnyCacheClearComm©) Client.png© BasicApi.php ©SyncOpportunity.php© SyncOpportunitiesJob.php© HubspotWebhookBatchSyncStrategy.php© WebhookSyncBatchProcessor.php ImportOpportunityBatch.php© JiminnySetEncryptedToke© JiminnyTokenInfoCommai© MakeSlackLiveCoachingC© ManageScimForTeam.phg© MarkBranchForEnvironme© MuteOrganizerChannel.phwImportbatchJoblrait.phpD Http/RateLimited.php© BaseRateLimiter.php© Hubspot/Service.phpu Hubspot//syncermenuuestrait.oho© OpportunitySyncTest.php© RateLimit.phpC) RateLimiterinstance.ono(C) ProviderRateLimiter.phpclass JiminnvDebuaCommand extends Commandc) PhoApm.php© PropagateCoachingFeedb 212c) Puraeconterences.ohp© PurgeSoftDeletedOpportu 213© PurgesyncBatchesCommi 214© RecalculateDealRisksCom 244(C) RemoveDeleteMarkersCo© RemoveExpiredNudgesCc 245(C) RemoveUnusedParticioanc) RocetslacticSearch.nhn© RestoreActivityCrmProvid 315© RestoreActivity TypeComn 310© RunAiCallScoringForUntyr© SeedActivities.php© SendNudgeExpirationWar© SyncActivity.php(9 Trockimnortod nhnl© WhichWorkerlsWorkingOn 335> 0 Scheduling© Kernel.phpv Mcontrante>D Acl• @ ActivitySearch> 0 AiAutomation> D Crm→ _ Date lime• ESv D Httr> M Requests1AoiResponse.ohoRateLimited.ohpRateLimitintertace.ohn>D Interactions> M Model> D Nudge> M Plavlist> D Repositoriesv M Servicec354) MCnlondarvMCrm• MciontM Drovidopublic function calculateFromAndToDatePeriod(Larbon strombare = null?Carbon Stolate = null:array ?...1 usageprivate function formatReportPer1odName(string Sfrequency, Carbon $from, Carbon Sto): stringi...s1 usagepublic function sanitizeFileName(string $fileName): stringt...hprivate function getPayLoad(AutomatedReportsService $automatedReportsService)i...hlusageprivate function rateLimitoSteam = Team:: find( id: 2):Sconfig = $team->getCrmConfigurationO:ScrmResolver = app( abstract: Crm0wnerResolver::class, ['team' => $team'integrationAdmin' => Steam->getOwnerO.'providerSlug' => Sconfiq->getProviderNameO.ScrmService = ScrmResolver->preparecrmServ1ce0for (Si = 0: Si < 10: Si++) {if ($i % 25 === 0) {Choose DeclarationSthis->info("SvncinglSthis->infof string: "Ma"@ 6 matchExactlyByEmail (MatchProspectsTrait .../app/Services/Crm/IntegrationApp/ServiceTraitm ơ matchExactlyByEmail (MatchCrmEntitiesInterface .../app/Contracts/Services/Crm)@ 6 matchExactlyByEmail (Service'. ../app/Services/Crm/Salesforce)() d matchExactlyByEmail (ServiceInterface .../app/Contracts/Services/Crm)ScrmService->matchExactlvB@ 8 matchExactlyByEmail (Service .../app/Services/Crm/Copper)d matchExactlyByEmail (Service...app/Services/Crm/Pinednivo)() d matchExactlyBvEmail (BullhornService .../app/Services/Crm/Bullhorn)lM) ơ matchExactlyBvEmail (Service .../app/Services/Crm/Huepot)M) d matchExactlyBvEmail (Service .../app/Services/Crm/Dummv)M d matchExactlyBvEmail (Service'...app/Services/crm/close)arQube for INE suadections: Netect more cecurity iccuec in vour DHP filec II Try SonarQube Cloud for free /I Download SorQuhe Sorver |l Iearn more /I Don't ack adain (todav 10-25)= custom.log X = laravel.log4 SF jjiminny@localhost]HS_local (jiminny@localhost]# console [PKol)0 hl 7 # Lukas/Stefka 121 - in 1h 54m100% C7Thu 7 May 15:36:08AskJiminnyReportActivityServiceTest vA console (eu)« console [STAGING]A5 A120 M5 A V353:39 UTF-8 # 4 spaces...
|
NULL
|
4965537499392315284
|
NULL
|
click
|
ocr
|
NULL
|
PhpStormINavigarecodeLaravelKeractorJOOISWindowFV PhpStormINavigarecodeLaravelKeractorJOOISWindowFV faVsco.js°9 master kProiectRateLimitException.php© SyncToUserPilot.phpC) RateLimitAwareWrapper.pnpC. IterateUserscommand.on© JiminnyCacheClearComm©) Client.png© BasicApi.php ©SyncOpportunity.php© SyncOpportunitiesJob.php© HubspotWebhookBatchSyncStrategy.php© WebhookSyncBatchProcessor.php ImportOpportunityBatch.php© JiminnySetEncryptedToke© JiminnyTokenInfoCommai© MakeSlackLiveCoachingC© ManageScimForTeam.phg© MarkBranchForEnvironme© MuteOrganizerChannel.phwImportbatchJoblrait.phpD Http/RateLimited.php© BaseRateLimiter.php© Hubspot/Service.phpu Hubspot//syncermenuuestrait.oho© OpportunitySyncTest.php© RateLimit.phpC) RateLimiterinstance.ono(C) ProviderRateLimiter.phpclass JiminnvDebuaCommand extends Commandc) PhoApm.php© PropagateCoachingFeedb 212c) Puraeconterences.ohp© PurgeSoftDeletedOpportu 213© PurgesyncBatchesCommi 214© RecalculateDealRisksCom 244(C) RemoveDeleteMarkersCo© RemoveExpiredNudgesCc 245(C) RemoveUnusedParticioanc) RocetslacticSearch.nhn© RestoreActivityCrmProvid 315© RestoreActivity TypeComn 310© RunAiCallScoringForUntyr© SeedActivities.php© SendNudgeExpirationWar© SyncActivity.php(9 Trockimnortod nhnl© WhichWorkerlsWorkingOn 335> 0 Scheduling© Kernel.phpv Mcontrante>D Acl• @ ActivitySearch> 0 AiAutomation> D Crm→ _ Date lime• ESv D Httr> M Requests1AoiResponse.ohoRateLimited.ohpRateLimitintertace.ohn>D Interactions> M Model> D Nudge> M Plavlist> D Repositoriesv M Servicec354) MCnlondarvMCrm• MciontM Drovidopublic function calculateFromAndToDatePeriod(Larbon strombare = null?Carbon Stolate = null:array ?...1 usageprivate function formatReportPer1odName(string Sfrequency, Carbon $from, Carbon Sto): stringi...s1 usagepublic function sanitizeFileName(string $fileName): stringt...hprivate function getPayLoad(AutomatedReportsService $automatedReportsService)i...hlusageprivate function rateLimitoSteam = Team:: find( id: 2):Sconfig = $team->getCrmConfigurationO:ScrmResolver = app( abstract: Crm0wnerResolver::class, ['team' => $team'integrationAdmin' => Steam->getOwnerO.'providerSlug' => Sconfiq->getProviderNameO.ScrmService = ScrmResolver->preparecrmServ1ce0for (Si = 0: Si < 10: Si++) {if ($i % 25 === 0) {Choose DeclarationSthis->info("SvncinglSthis->infof string: "Ma"@ 6 matchExactlyByEmail (MatchProspectsTrait .../app/Services/Crm/IntegrationApp/ServiceTraitm ơ matchExactlyByEmail (MatchCrmEntitiesInterface .../app/Contracts/Services/Crm)@ 6 matchExactlyByEmail (Service'. ../app/Services/Crm/Salesforce)() d matchExactlyByEmail (ServiceInterface .../app/Contracts/Services/Crm)ScrmService->matchExactlvB@ 8 matchExactlyByEmail (Service .../app/Services/Crm/Copper)d matchExactlyByEmail (Service...app/Services/Crm/Pinednivo)() d matchExactlyBvEmail (BullhornService .../app/Services/Crm/Bullhorn)lM) ơ matchExactlyBvEmail (Service .../app/Services/Crm/Huepot)M) d matchExactlyBvEmail (Service .../app/Services/Crm/Dummv)M d matchExactlyBvEmail (Service'...app/Services/crm/close)arQube for INE suadections: Netect more cecurity iccuec in vour DHP filec II Try SonarQube Cloud for free /I Download SorQuhe Sorver |l Iearn more /I Don't ack adain (todav 10-25)= custom.log X = laravel.log4 SF jjiminny@localhost]HS_local (jiminny@localhost]# console [PKol)0 hl 7 # Lukas/Stefka 121 - in 1h 54m100% C7Thu 7 May 15:36:08AskJiminnyReportActivityServiceTest vA console (eu)« console [STAGING]A5 A120 M5 A V353:39 UTF-8 # 4 spaces...
|
3689
|
NULL
|
NULL
|
NULL
|
|
3690
|
135
|
4
|
2026-05-07T12:36:08.008643+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157368008_m1.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"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(wbl# Lukas/Stefka 121 - in 1h 54 m100% [8DEV (docker)DOCKERC &1DEV (docker)H82APP (-zsh)worker-analytics:worker-analytics_00: stoppedworker-crm-update:worker-crm-update_00: stoppedworker-download:worker-download_00: stoppedworker-nudges:worker-nudges_00: stoppedworker:worker_00: stoppedJiminny-worker-processing-1:j1minny-worker-processing-1_00: stoppedworker-audio:worker-audio_00: stoppedworker-calendar:worker-calendar_00:stoppedworker-conferences:worker-conferences_00: stoppedworker-crm-sync:worker-crm-sync_00: stoppedworker-emails:worker-emails_00: stoppedartisan-schedule:artisan-schedule_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# php artisan jiminny:debugMatching contact 0root@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 15:36:08T₴1₴6DEV...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3689
|
136
|
4
|
2026-05-07T12:36:06.379160+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157366379_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Search
matchExactlyByEmail (MatchProspectsTrait .. Search
matchExactlyByEmail (MatchProspectsTrait .../app/Services/Crm/IntegrationApp/ServiceTraits), public method
matchExactlyByEmail (MatchCrmEntitiesInterface .../app/Contracts/Services/Crm), public abstract method
matchExactlyByEmail (Service .../app/Services/Crm/Salesforce), public method
matchExactlyByEmail (ServiceInterface .../app/Contracts/Services/Crm), public abstract method
matchExactlyByEmail (Service .../app/Services/Crm/Copper), public method
matchExactlyByEmail (Service .../app/Services/Crm/Pipedrive), public method
matchExactlyByEmail (BullhornService .../app/Services/Crm/Bullhorn), public method
matchExactlyByEmail (Service .../app/Services/Crm/Hubspot), public method
matchExactlyByEmail (Service .../app/Services/Crm/Dummy), public method
matchExactlyByEmail (Service .../app/Services/Crm/Close), public method
Choose Declaration...
|
[{"role":"AXTextField","text [{"role":"AXTextField","text":"Search","depth":1,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"matchExactlyByEmail (MatchProspectsTrait .../app/Services/Crm/IntegrationApp/ServiceTraits), public method","depth":4,"bounds":{"left":0.22606383,"top":0.79010373,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"matchExactlyByEmail (MatchCrmEntitiesInterface .../app/Contracts/Services/Crm), public abstract method","depth":4,"bounds":{"left":0.22606383,"top":0.8076616,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"matchExactlyByEmail (Service .../app/Services/Crm/Salesforce), public method","depth":4,"bounds":{"left":0.22606383,"top":0.82521945,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"matchExactlyByEmail (ServiceInterface .../app/Contracts/Services/Crm), public abstract method","depth":4,"bounds":{"left":0.22606383,"top":0.8427773,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"matchExactlyByEmail (Service .../app/Services/Crm/Copper), public method","depth":4,"bounds":{"left":0.22606383,"top":0.8603352,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"matchExactlyByEmail (Service .../app/Services/Crm/Pipedrive), public method","depth":4,"bounds":{"left":0.22606383,"top":0.87789303,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"matchExactlyByEmail (BullhornService .../app/Services/Crm/Bullhorn), public method","depth":4,"bounds":{"left":0.22606383,"top":0.8954509,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"matchExactlyByEmail (Service .../app/Services/Crm/Hubspot), public method","depth":4,"bounds":{"left":0.22606383,"top":0.91300875,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"matchExactlyByEmail (Service .../app/Services/Crm/Dummy), public method","depth":4,"bounds":{"left":0.22606383,"top":0.93056667,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"matchExactlyByEmail (Service .../app/Services/Crm/Close), public method","depth":4,"bounds":{"left":0.22606383,"top":0.9481245,"width":0.25332448,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Choose Declaration","depth":1,"bounds":{"left":0.2293883,"top":0.76376694,"width":0.24667554,"height":0.026336791},"on_screen":true,"role_description":"text"}]...
|
4681487929918222738
|
338522765764748648
|
visual_change
|
accessibility
|
NULL
|
Search
matchExactlyByEmail (MatchProspectsTrait .. Search
matchExactlyByEmail (MatchProspectsTrait .../app/Services/Crm/IntegrationApp/ServiceTraits), public method
matchExactlyByEmail (MatchCrmEntitiesInterface .../app/Contracts/Services/Crm), public abstract method
matchExactlyByEmail (Service .../app/Services/Crm/Salesforce), public method
matchExactlyByEmail (ServiceInterface .../app/Contracts/Services/Crm), public abstract method
matchExactlyByEmail (Service .../app/Services/Crm/Copper), public method
matchExactlyByEmail (Service .../app/Services/Crm/Pipedrive), public method
matchExactlyByEmail (BullhornService .../app/Services/Crm/Bullhorn), public method
matchExactlyByEmail (Service .../app/Services/Crm/Hubspot), public method
matchExactlyByEmail (Service .../app/Services/Crm/Dummy), public method
matchExactlyByEmail (Service .../app/Services/Crm/Close), public method
Choose Declaration...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3688
|
136
|
3
|
2026-05-07T12:36:04.414555+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157364414_m2.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
120
5
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
// if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
// }
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"on_screen":true,"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":"5","depth":4,"bounds":{"left":0.48038563,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"bounds":{"left":0.49035904,"top":0.19952115,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"5","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n// if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n// }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n// if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n// }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
8992110238679606277
|
3603295541575380363
|
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
5
120
5
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
// if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
// }
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
3685
|
NULL
|
NULL
|
NULL
|
|
3687
|
135
|
3
|
2026-05-07T12:36:04.357489+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157364357_m1.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
120
5
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
// if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
// }
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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":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":"5","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"5","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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n// if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n// }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n// if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n// }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
8992110238679606277
|
3603295541575380363
|
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
5
120
5
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
// if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
// }
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
3686
|
NULL
|
NULL
|
NULL
|
|
3684
|
136
|
1
|
2026-05-07T12:35:48.959180+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157348959_m2.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
1
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
// if ($i % 1 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"on_screen":true,"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.4710771,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"5","depth":4,"bounds":{"left":0.48038563,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"bounds":{"left":0.49035904,"top":0.19952115,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n// if ($i % 1 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n// if ($i % 1 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
-6311466412596879756
|
-6772435049932821109
|
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
1
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
// if ($i % 1 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
3682
|
NULL
|
NULL
|
NULL
|
|
3683
|
135
|
1
|
2026-05-07T12:35:48.959009+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157348959_m1.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
1
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
// if ($i % 1 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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":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":"5","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n// if ($i % 1 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n// if ($i % 1 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
-6311466412596879756
|
-6772435049932821109
|
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
1
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
// if ($i % 1 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
3681
|
NULL
|
NULL
|
NULL
|
|
3682
|
136
|
0
|
2026-05-07T12:35:46.624339+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157346624_m2.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
121
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 1 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"on_screen":true,"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":"5","depth":4,"bounds":{"left":0.48105052,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"121","depth":4,"bounds":{"left":0.49102393,"top":0.19952115,"width":0.011303191,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 1 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 1 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
-5420194068516444853
|
-5619513545325974133
|
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
5
121
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 1 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3681
|
135
|
0
|
2026-05-07T12:35:46.423029+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157346423_m1.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
121
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 1 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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":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":"5","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"121","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 1 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 1 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
-5420194068516444853
|
-5619513545325974133
|
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
5
121
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 1 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3680
|
NULL
|
0
|
2026-05-07T12:35:40.497883+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157340497_m2.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"on_screen":true,"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":"5","depth":4,"bounds":{"left":0.48038563,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"bounds":{"left":0.49035904,"top":0.19952115,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
-5974274438448015472
|
3603858491526180235
|
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
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
3677
|
NULL
|
NULL
|
NULL
|
|
3679
|
NULL
|
0
|
2026-05-07T12:35:40.497608+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157340497_m1.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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":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":"5","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
-5974274438448015472
|
3603858491526180235
|
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
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
3678
|
NULL
|
NULL
|
NULL
|
|
3676
|
133
|
23
|
2026-05-07T12:35:27.443424+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157327443_m1.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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":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":"5","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
-5974274438448015472
|
3603858491526180235
|
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
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
3673
|
NULL
|
NULL
|
NULL
|
|
3675
|
134
|
34
|
2026-05-07T12:35:27.281938+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157327281_m2.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"on_screen":true,"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":"5","depth":4,"bounds":{"left":0.48038563,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"bounds":{"left":0.49035904,"top":0.19952115,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 10; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
-5974274438448015472
|
3603858491526180235
|
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
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 10; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
3674
|
NULL
|
NULL
|
NULL
|
|
3674
|
134
|
33
|
2026-05-07T12:35:22.656027+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157322656_m2.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 120; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"on_screen":true,"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":"5","depth":4,"bounds":{"left":0.48038563,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"bounds":{"left":0.49035904,"top":0.19952115,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 120; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 120; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
8266549271677006749
|
3603859041281994123
|
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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 120; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3673
|
133
|
22
|
2026-05-07T12:35:22.530166+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157322530_m1.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 120; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
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":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":"5","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 120; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 120; $i++) {\n if ($i % 25 === 0) {\n// $this->info(\"Syncing opportunity {$i}\");\n $this->info(\"Matching contact {$i}\");\n }\n// $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('coolrobot@hubspot.com');\n }\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}]...
|
8266549271677006749
|
3603859041281994123
|
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
5
120
4
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use Illuminate\Console\Command;
use InvalidArgumentException;
use Jiminny\Jobs\AutomatedReports\RequestGenerateAskJiminnyReportJob;
use Jiminny\Jobs\AutomatedReports\SendReportMailJob;
use Jiminny\Jobs\JobDispatcherInterface;
use Jiminny\Models\Activity;
use Jiminny\Models\AutomatedReport;
use Jiminny\Models\AutomatedReportResult;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Jiminny\Repositories\AutomatedReportsRepository;
use Jiminny\Services\Activity\CrmOwnerResolver;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Services\UserPilot\UserPilotClient;
/**
* Class JiminnyDebugCommand
*
* @package Jiminny\Console\Commands
*/
class JiminnyDebugCommand extends Command
{
public const string FREQUENCY_DAILY = 'daily';
public const string FREQUENCY_WEEKLY = 'weekly';
public const string FREQUENCY_MONTHLY = 'monthly';
public const string FREQUENCY_QUARTERLY = 'quarterly';
public const string FREQUENCY_ONE_OFF = 'one_off';
protected $signature = 'jiminny:debug';
public function handle(
JobDispatcherInterface $jobDispatcher,
AutomatedReportsService $automatedReportsService,
AutomatedReportsRepository $automatedReportsRepository,
UserPilotClient $userPilotClient
): void {
$this->rateLimit();
exit(1);
$report = AutomatedReport::find(71);
$last = AutomatedReportResult::query()
->where('report_id', $report->getId())
->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])
// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)
->whereDate('created_at', CarbonImmutable::now()->toDateString())
->latest()
->first();
$this->info("Last: {$last->getId()}");
exit(1);
$user = User::find(143);
// $count = $automatedReportsRepository->countUserReports($user);
// $this->info("Count: {$count}");
// $count = $automatedReportsRepository->countAllUserReports($user);
// $this->info("All count: {$count}");
$payload = [
'report_type' => 'ask_jiminny',
'frequency' => 'weekly',
];
$userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);
exit(1);
$now = Carbon::now()->subDay(1);
$this->info("Now: {$now->toDateTimeString()}");
$weekStart = Carbon::getWeekStartsAt();
$this->info("Now: {$weekStart}");
// $from = $now->copy()->previousWeekday()->startOfDay();
// $to = $now->copy()->previousWeekday()->endOfDay();
// $fromOld = $now->copy()->subWeeks(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subWeek()->startOfWeek();
// $toNew = $now->copy()->subWeek()->endOfWeek();
// $fromOld = $now->copy()->subMonths(1)->startOfDay();
// $toOld = $now->copy()->subDay()->endOfDay();
// $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();
// $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();
$fromOld = $now->copy()->subMonths(3)->startOfDay();
$toOld = $now->copy()->subDay()->endOfDay();
$fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();
$toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();
$this->info("From old: {$fromOld->toDateTimeString()}");
$this->info("To old: {$toOld->toDateTimeString()}");
$this->info("From new: {$fromNew->toDateTimeString()}");
$this->info("To new: {$toNew->toDateTimeString()}");
exit(1);
$report = AutomatedReport::find(71);
$job = new RequestGenerateAskJiminnyReportJob($report->getUuid());
$jobDispatcher->dispatch($job);
exit(1);
// $this->formatDate($jobDispatcher);
// $this->sendMail($jobDispatcher, $automatedReportsService);
// $this->crmService();
$this->getPayload($automatedReportsService);
exit(1);
}
private function crmService()
{
$activity = Activity::find(418141);
$team = Team::find(19);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
$crmService->createTranscriptNotes($activity);
}
private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)
{
$reportUuid = '';
// $report = $automatedReportsService->getReportResult($reportUuid);
$report = AutomatedReportResult::find(275);
$validRecipients = $automatedReportsService->getValidRecipientUsers(
$report->getReport(),
includeJiminny: true,
);
$recipient = $validRecipients[0];
$fileName = $automatedReportsService->getReportFileName($report);
$typeName = $report->getReport()->getCustomName()
?? $automatedReportsService->getReportTypeName($report);
$teamsName = $automatedReportsService->getReportTeamsName($report);
$periodName = $automatedReportsService->getReportPeriodName($report);
$s3Path = $automatedReportsService->getMediaPath($report);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));
$jobDispatcher->dispatch(
new SendReportMailJob(
reportUuid: $report->getUuid(),
s3Path: $s3Path,
recipientEmail: $recipient['email'],
recipientName: $recipient['name'] ?? null,
fileName: $fileName,
typeName: $typeName,
teamsName: $teamsName,
periodName: $periodName,
isAskJiminny: true,
)
);
exit(1);
}
private function formatDate(JobDispatcherInterface $jobDispatcher): void
{
$customName = 'Custom report name';
// $frequency = self::FREQUENCY_DAILY;
// $frequency = self::FREQUENCY_WEEKLY;
$frequency = self::FREQUENCY_MONTHLY;
// $frequency = self::FREQUENCY_QUARTERLY;
// $frequency = self::FREQUENCY_ONE_OFF;
$period = $this->calculateFromAndToDatePeriod($frequency);
$from = $period['fromDate'];
$to = $period['toDate'];
$periodName = $this->formatReportPeriodName($frequency, $from, $to);
$filenameSuffix = null;
if ($customName) {
if ($filenameSuffix) {
$customName .= " {$filenameSuffix}";
}
$result = $this->sanitizeFileName("{$customName} - {$periodName}");
}
$this->info($result);
}
public function calculateFromAndToDatePeriod(
string $frequency,
?Carbon $fromDate = null,
?Carbon $toDate = null
): array {
if ($frequency === self::FREQUENCY_ONE_OFF) {
return [
'fromDate' => $fromDate,
'toDate' => $toDate,
];
}
$now = Carbon::now();
return match ($frequency) {
self::FREQUENCY_DAILY => [
'fromDate' => $now->copy()->subDay()->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_WEEKLY => [
'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_MONTHLY => [
'fromDate' => $now->copy()->subMonths(1)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
self::FREQUENCY_QUARTERLY => [
'fromDate' => $now->copy()->subMonths(3)->startOfDay(),
'toDate' => $now->copy()->subDay()->endOfDay(),
],
default => throw new InvalidArgumentException("Unsupported frequency: {$frequency}"),
};
}
private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string
{
$fromYear = $from->format('Y');
$toYear = $to->format('Y');
$differentYears = $fromYear !== $toYear;
switch ($frequency) {
case self::FREQUENCY_DAILY:
return $from->format('j M Y');
case self::FREQUENCY_QUARTERLY:
// 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ
$startMonth = $from->format('M');
$endMonth = $to->copy()->subMonth();
$endMonthName = $endMonth->format('M');
$endMonthYear = $endMonth->format('Y');
if ($differentYears) {
return "{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}";
}
return "{$startMonth} - {$endMonthName} {$toYear}";
case self::FREQUENCY_MONTHLY:
// 'May 2025' - monthly reports are always within the same year
return $from->format('M Y');
case self::FREQUENCY_WEEKLY:
// '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ
$startDay = $from->format('j');
$endDay = $to->format('j');
$startMonth = $from->format('M');
$endMonth = $to->format('M');
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
if ($startMonth !== $endMonth) {
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
}
return "{$startDay} - {$endDay} {$endMonth} {$toYear}";
case self::FREQUENCY_ONE_OFF:
// '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ
$startDay = $from->format('j');
$startMonth = $from->format('M');
$endDay = $to->format('j');
$endMonth = $to->format('M');
// If same month and year, use a format like '2-31 May 2025'
if ($startMonth === $endMonth && ! $differentYears) {
return "{$startDay} - {$endDay} {$startMonth} {$toYear}";
}
// If different years, include both years
if ($differentYears) {
return "{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}";
}
// Same year but different months
return "{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}";
default:
// Default format for unknown frequencies
return $from->format('j M Y') . ' - ' . $to->format('j M Y');
}
}
public function sanitizeFileName(string $fileName): string
{
return str_replace(['/', '\\'], '-', $fileName);
}
private function getPayload(AutomatedReportsService $automatedReportsService)
{
$reportResult = AutomatedReportResult::find(269);
$automatedReport = $reportResult->getReport();
$activityIds = [1,2,3];
$payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(
automatedReport: $automatedReport,
reportResult: $reportResult,
activityIds: $activityIds,
);
\Illuminate\Support\Facades\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));
}
private function rateLimit()
{
$team = Team::find(2);
$config = $team->getCrmConfiguration();
$crmResolver = app(CrmOwnerResolver::class, [
'team' => $team,
'integrationAdmin' => $team->getOwner(),
'providerSlug' => $config->getProviderName(),
]);
$crmService = $crmResolver->prepareCrmService();
for ($i = 0 ; $i < 120; $i++) {
if ($i % 25 === 0) {
// $this->info("Syncing opportunity {$i}");
$this->info("Matching contact {$i}");
}
// $crmService->syncOpportunity('374720564');
$crmService->matchExactlyByEmail('[EMAIL]');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3666
|
134
|
28
|
2026-05-07T12:35:01.676040+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157301676_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
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"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.4820479,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":4,"bounds":{"left":0.49202126,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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":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}]...
|
2639052714236570666
|
6378757184196315236
|
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
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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...
|
3664
|
NULL
|
NULL
|
NULL
|
|
3665
|
133
|
19
|
2026-05-07T12:35:00.482737+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157300482_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
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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":"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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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":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}]...
|
2639052714236570666
|
6378757184196315236
|
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
Sync Changes
Hide This Notification
Code changed:
Hide
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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
|
|
3664
|
134
|
27
|
2026-05-07T12:34:31.053489+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157271053_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
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"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.4820479,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":4,"bounds":{"left":0.49202126,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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":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}]...
|
2639052714236570666
|
6378757184196315236
|
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
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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
|
|
3663
|
133
|
18
|
2026-05-07T12:34:29.491119+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157269491_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
Analyzing…
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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":"AXStaticText","text":"Analyzing…","depth":4,"on_screen":true,"role_description":"text"},{"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":"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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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":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}]...
|
4059623151426183482
|
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
Analyzing…
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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
|
|
3662
|
134
|
26
|
2026-05-07T12:34:29.485167+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157269485_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
Analyzing…
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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":"AXStaticText","text":"Analyzing…","depth":4,"bounds":{"left":0.96542555,"top":0.07581804,"width":0.019946808,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXTextArea","text":"Editor for custom.log","depth":4,"bounds":{"left":0.5475399,"top":0.0726257,"width":0.44082448,"height":0.9066241},"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.4820479,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"68","depth":4,"bounds":{"left":0.49202126,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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 private function isHubspotRateLimit(Throwable $e): bool\n {\n return method_exists($e, 'getCode') && (int) $e->getCode() === 429;\n }\n\n private 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":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}]...
|
4059623151426183482
|
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
Analyzing…
Editor for custom.log
Sync Changes
Hide This Notification
Code changed:
Hide
2
68
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;
}
}
private function isHubspotRateLimit(Throwable $e): bool
{
return method_exists($e, 'getCode') && (int) $e->getCode() === 429;
}
private function parseRetryAfter(Throwable $e): int
{
if (method_exists($e, 'getResponseHeaders')) {
$headers = $e->getResponseHeaders() ?: [];
$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...
|
3661
|
NULL
|
NULL
|
NULL
|
|
3659
|
134
|
24
|
2026-05-07T12:34:22.521035+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157262521_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
Search History
Hubspot
New Line
Replace History...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"","depth":2,"bounds":{"left":0.8976064,"top":0.92098963,"width":0.06948138,"height":0.011173184},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":2,"bounds":{"left":0.8976064,"top":0.952913,"width":0.06948138,"height":0.011173184},"on_screen":true,"role_description":"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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}]...
|
2897863107278384685
|
-8132224210615194686
|
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
Search History
Hubspot
New Line
Replace History
0(5)PhostormINavigarecodeFV faVsco.jsm Bullhorn© Client.php >obasicapl.oneD CloseD Copper> D CrmObjectsD DecorateActivity> Dummy> O Helpersv @ HubspotT ImportBatchJobTrait.phgHitp/RateLimited.png( Hubspot/.../SyncCrmEntitiesTrait.php(C) ProviderRateLimiter.php_ AccountsyncstrateayActions_contactsyncstrateayO DTO463D rielosu Journa0 Metadatav _ OpportunitvSvncStrate> D ConcernsC) HubspotlastModitie© HubspotLastModifie(c) Huosoot LastModitie© HubspotLastModifieC) HubsootLastModifieC) HubsnotSinaleSvncC. HubsnotSvncStrate@ HubsnotWebhookBm PadinationProspectSearchStratesM PedicServiceTraitsT OpportunitySyncTraT SyncCrmEntitiesTraT SyncFieldsTrait.phpWriteCrmTrait.phpMittile> C Webhook|© BatchSyncCollector.ph© BatchSvncRedisServicC) [EMAIL]) DecorateActiviv.onoCFieldDerinitions.onoC) FieldivoeConverter.of1 Hubspotclientinterfac:494C) Hubsoot TokenManade© PayloadBuilder.phpC) RemoteCrm@biectMan9) ResnonseNormalize nh(c) Service nhn@ SvncFieldAction.phpC) SvncPelatedActivitvM:class Cuient extends BasecLient imolements Hubspotc ientinterfacepublic functinnaagetcootartBy d Cstraneosecmnoovaruaxustie(ds): arraythrow new CrmException( message: 'Contact not found'):'id' => Scontact-›getIdo.properties' => Scontact-›qetProvertresol* This is emai search reauest that Hubsoot offers as Ger more denerous quotapublic function getContactByEmail(string Semail, array $fields = [J): arraytry -Scontact = Sthis->aetNewInstance@->crmO->contacts@->hasi.cAniO->aetBv1dimnlode & senarator "1 Sfields)dicrlved. Talse,id_property: 'email'return'id' => Scontact-›getIdo.'properties' => Scontact->qetPropertieso} catch (ContactApiException $e) {Sthis->loq->info('[Hubspot] Failed to fetch contact'. ['ema1l' => Sema1u'reason' => Se->qetMessageoreturn1:* athrows Ermsycentionpublic function fetchProperty(string $objectType, string $propertyId): Property(...}SonarQube 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)kateLImitawarewrapper.ongsyneopporunitesJoo.pnp42 A68 X2 ^Lukas/Stefka 121 - in 1h 56 mInu / May 10.34-24AskJiminnyReportActivityServiceTest -= custom.log« SF [jiminny@localhost]HS_local (jiminny@localhost]« console [PROD]& console [STAGINGI22R Match case[2026-05-07 12:28:14] local.INFO:JmInnya consoLen connanas, comnano erun remory usage for conmand "conmano"e"araLenstiont cor-accve ces"r"memoryberorevommand nnio"woz.or"memo w[2026-05-07 12:28:17] local.INF0:[SocialAccountServicel Fetching token {"socialAccountId":1499 "provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344"|2020-05-01 12.20.1/ Local.LNrU:[2026-05-07 12:28:17] local.INF0:SOCLaLACCOUnLseNveceloKenneeus etiesinnoEuSOctaLACCOUncLONe 47rOnOVedеnн nUDsро сизз всом нешатоютоми4655514-0545-40407осма-сOCOВ[EncryptedTokenManager] Generating access token. {"mode": "legacy"} {"correlation_id": "273355f2-6315-4b20-bc9a-c26c681d6344", "trace_id" : "5ea79[2026-05-07 12:28:171 local.INF0: [SocialAccountServicel Refreshing token from provider {"socialAccountId":1499, "providen": "hubspot" "refreshToken" : "96f94c623a404e02ebdbf07f1b2026-05-07 12:28:18 Local.NOTICE: Monitoring start{"correlation_ id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5" "trace_id"."b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}12026-05-08282888ocaLNOMCEH MOn tonne endcorrelation1cнаa0b0-0006-448а-bocс-as0415b4aeb5"7taсе ОяОВеруе5-844-410-90на-азо«сьен5тн2шE2026-05-07 12:28:18 Local.INF0Sf"correlation id"."273355f2-6315-4b20-bc9a-c26c681d6344" "trace id". "5ea79a26-c838-48e8-9913-93ad50814612026-05-07 12:28 18 LocalINF0:[2026-05-07 12:28:181 local. INF0:SocialAccountloserver Access token was modhrled, encrvotinol"correlation 1d":[CREDIT_CARD]-0c9a-026068106544""trace 1d":"Sea72a26.[SocialAccountService] Token refreshed {"socialAccountId":1499, "provider": "hubspot", "state": "connected"} {"correlation_id":"273355f2-6315-4b22026-05-07 12:28:18 Local.INF0:[2026-05-07 12:28:191 local, INF0:comownerReso ver Dntednattion owner matched as CRM ownenwcem orovader hubspotucom ownen r28.team a Wconnellatiion ШR 206k15512[Hubspot] Failed to fetch opportunity {"crm_id":"374720564", "reason":"[429] Client error: 'GET https://api.hubapi.com/crm/v3/objects/deals/371\"status)":"error)", "message\":\"You have reached your ten_secondly_rolling limit.", "errorType)":"RATE_LIMIT)", "correlationid)" (truncated...)"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344"', "trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}2026-05-07 12-28-191 1oca1 ERROR 420 Mhient erron.GEl htts:an.huhan.com/com/w/nhlects/deals/374205642noonentles-hs_ohglect1d%20dealname.associat.ions=comnan.les%2%c{"status":"error", "message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT", "correlationid" (truncated...)"pycention". " lohiec+))(HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error:•GFT httns://ani.huhani.com/com/v3/ohiects/deals/3747205642nnonentiec=hsoha{\"status\":\"error)",\"message)":\"You have reached your ten_secondly_rolling limit.","errorType)":"RATE_LIMIT)","correlationId)" (truncated...)at/home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)- [stacktrace]—#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot|\Client|\Crm\\Deals|\Api|\BasicApi->getByIdWithHttpInfo(^374720564', 'hs_object_id#1/home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\ \BasicApi->getById('374720564', 'hs_object_id,de...',#2/home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/0pportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)- #3 /home/jiminny/app/Console/Commands/JiminnyDebuqCommand.php (351): Jiminny|(Services||Crm|\Hubspotl|Service->syncOpportunity(^374720564')- #4 /home/jiminny/app/Console/Commands/JiminnyDebuqCommand.php(44): Jiminny\Console\Commands|JiminnyDebugCommand->rateLimitO= #5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny||Consolel|Commands||JiminnyDebugCommand->handLe(Object(Jiminny||Jobs||JobDispat#6/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::Illuminate\Container{closurelO#7/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate Containerl\Util::unwrapIfClosure(Obiect(Closure))= #8 /home/timinny/vendor/laraveZ/franework/src/1lluminate/Container/BoundMethod,pho (35): Illuminatel |Containerl |BoundMethod: :ca11BoundMethod (CObtect (T1Luminatel | Foundationl lADD# Tnome1aminnyvendor/laraveutr.meworkzsec a a a uumanatez contanner contasner,oho vssar aa umnate acontannen a Boundet noo acal a cuonect o a u uma nate aoundati on aVADol I1cat 1OnDIPAT#10/home/jiminnv/vendor/laravel/framework/src/Illuminate/Console/Command.phv(211): Illuminatel\Container|\Container->cal1(Arrav)#iu Thome /Timinny vendor/svmfony.and//Command.oho (3410: TluminateConsoleConnand->execute(Obiect SumfonyComoonent Console inout Aravinout). Obiect anlumina#12/home/jiminnv/vendor/laravel/framework/src/Illuminate/Console/Command.pho(180): Svmfonv|\Component|\Consolel\Commland! \Command->run(Obiect (Svmfonv) \Componentl \Consolel \InouFK 7home/E5iminny/vendon//symtonv/ consol le//Aoo 5 cation -oho GunvDR tu lumi nate uonso la ucommand»» nun cobr e ci es vmtonv comoonenta aconso le iunouta lAray nouta. obrtect esvm ionv Ncomoon#14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand),#151Zhome/E5m nny/ vendor/symtonv/ Conso le//Aoo 5 cataon-Oho 0195)F Sem ony ucomoonenta Nconso Le IVADo l6 catiion->doRun Cb leci 7 esvm on acomoonenta Nconsol le lv noura lVAcay noua r obiect TeSV= #16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony|\Component| \Consolel\Application->run(0biect(Svmfonv||Component||Consolelwwhome/E6m.Innw//Mendow/lanavelWEdoamewon.scc7atllmTattel/soundatalon//An0GTcataTonunh0/Gl/k1.9katbmElnatteEoundatalon.lonsolalkernehandleldlElecasvmonv/uTomnonentalionsolel#18 /home/&iminnv/antisan(13): Tlluminatel|Foundation| \AnnLication->handleCommand(0biect(Svmfonv|\Comnonent||Console||Tnnut|\AravTnnut))#10 <main?- "} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344", "trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}12026-05-07 1222842010calLNEDR Vimiinny Monsolla Wommands VCommandaanun Memonv nisade hefone stantiino command Elcommand" «"masilhoyaskin-Wistcanefnesh" "memonvRefoneRommandTnMhlr[2026-05-07 12:28:20] Local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command" : "mailbox:skip-lists:refresh", "memoryBeforeCommandInMb" : 62.0, "memoryCAmMANd EWCommanduClmAtllhAydhatChanencocell lmemoayRefanedommandiaMЬШa10 n[2026-05-07 12:28:24] local.INF0:12024-05-07 12.29.241 1oc01 TAE0•[EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8"' "trace_id":"67798138[EmailSchedule] FINISHED batch process {"host":"docker lamp 1" "processed":0} {"correlation id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8" "trace[2026-05-07 12:28:24] local.INF0: Jiminny|Console\Commands\Command::run Memory usage for command {"command": "mailbox:batch:process", "memoryBeforeCommandInMb" :62.0, "memoryAfter[2026-05-07 12:28:27] local.INF0: Jiminny|Console\Commands\Command::run Memory usage before starting command {"command": "conference:moniton:count", "memoryBeforeCommandInMb" : 62[2026-05-07 12:28:27] local.INF0: Running conference:moniton:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:001 {"conrelation id":"a4e5e18f-9f8c-4196-[2026-05-07 12:28:27] local.INF0:[conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation id":"a4e5e18f-9f8c-4196-ace0-bf66W Windsurf Teamio 4 spaces...
|
3655
|
NULL
|
NULL
|
NULL
|
|
3658
|
134
|
23
|
2026-05-07T12:33:58.816485+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157238816_m2.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/Service.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"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":"Search Backward","depth":4,"bounds":{"left":0.7130984,"top":0.07821229,"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":"Search Forward","depth":4,"bounds":{"left":0.72174203,"top":0.07821229,"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":"Match сase","depth":4,"bounds":{"left":0.73038566,"top":0.07821229,"width":0.032247342,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"bounds":{"left":0.76263297,"top":0.07821229,"width":0.023271276,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"bounds":{"left":0.7859042,"top":0.07821229,"width":0.022938829,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"bounds":{"left":0.8088431,"top":0.08220271,"width":0.0019946808,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.97539896,"top":0.07821229,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33:11] local.NOTICE: Monitoring start {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] 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\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}","depth":4,"bounds":{"left":0.52859044,"top":0.016759777,"width":0.47140956,"height":0.98324025},"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33:11] local.NOTICE: Monitoring start {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] 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\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}","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":"7","depth":4,"bounds":{"left":0.46143618,"top":0.19952115,"width":0.0076462766,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"48","depth":4,"bounds":{"left":0.4710771,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.48337767,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","depth":4,"bounds":{"left":0.49268618,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.5049867,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
3655
|
NULL
|
NULL
|
NULL
|
|
3657
|
133
|
16
|
2026-05-07T12:33:58.905005+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157238905_m1.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/Service.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"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":"Hubspot","depth":4,"on_screen":true,"value":"Hubspot","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":"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":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search All","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Backward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Forward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match сase","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"on_screen":true,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33:11] local.NOTICE: Monitoring start {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] 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\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33:11] local.NOTICE: Monitoring start {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] 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\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}","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":"7","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"48","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n// 'firstname',\n// 'lastname',\n// 'country',\n// 'phone',\n// 'mobilephone',\n// 'jobtitle',\n// 'hubspot_owner_id',\n// 'associatedcompanyid',\n// 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
3656
|
NULL
|
NULL
|
NULL
|
|
3656
|
133
|
15
|
2026-05-07T12:33:28.300251+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157208300_m1.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"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":"Hubspot","depth":4,"on_screen":true,"value":"Hubspot","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":"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":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search All","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Backward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Forward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match сase","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"on_screen":true,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33:11] local.NOTICE: Monitoring start {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] 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\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33:11] local.NOTICE: Monitoring start {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] 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\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}","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":"5","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 120; $i++) {\n if ($i % 25 === 0) {\n $this->info(\"Syncing opportunity {$i}\");\n }\n $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('374720564');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 120; $i++) {\n if ($i % 25 === 0) {\n $this->info(\"Syncing opportunity {$i}\");\n }\n $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('374720564');\n }\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}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3655
|
134
|
22
|
2026-05-07T12:33:28.300795+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157208300_m2.jpg...
|
PhpStorm
|
faVsco.js – JiminnyDebugCommand.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"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":"Search Backward","depth":4,"bounds":{"left":0.7130984,"top":0.07821229,"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":"Search Forward","depth":4,"bounds":{"left":0.72174203,"top":0.07821229,"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":"Match сase","depth":4,"bounds":{"left":0.73038566,"top":0.07821229,"width":0.032247342,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"bounds":{"left":0.76263297,"top":0.07821229,"width":0.023271276,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"bounds":{"left":0.7859042,"top":0.07821229,"width":0.022938829,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"bounds":{"left":0.8088431,"top":0.08220271,"width":0.0019946808,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.97539896,"top":0.07821229,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33:11] local.NOTICE: Monitoring start {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] 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\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}","depth":4,"bounds":{"left":0.52859044,"top":0.016759777,"width":0.47140956,"height":0.98324025},"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33:06] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"6ec4a59c-b750-4e78-b62c-82201ed74d42\",\"trace_id\":\"573ba9c3-2037-4839-8450-3753c32a5ba1\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33: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\":\"5aeb38c2-acb7-4484-9e8a-2eab5f462c98\",\"trace_id\":\"cb8387a1-7210-4f64-b774-8254027be2e2\"}\n[2026-05-07 12:33:11] local.NOTICE: Monitoring start {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d569c6f7-af8a-4e7c-ad7c-6a9c93742805\",\"trace_id\":\"b7f04e6c-6e92-4b67-a086-155cdee1f21a\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:15] 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\":\"3043aa1e-9452-43d3-b2dc-5eb37c1c363f\",\"trace_id\":\"998cb076-82f6-4b19-9b55-85ede6fb0c6f\"}\n[2026-05-07 12:33:17] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:17] 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\":\"e5f3c27a-127e-492c-a991-abea22eb4895\",\"trace_id\":\"dd53a3c6-3f9b-40be-86fe-7a4fac215823\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}\n[2026-05-07 12:33:19] 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\":\"793230e9-3872-4acc-bb2c-3c740c6f53b0\",\"trace_id\":\"5d7421f8-c73a-40e3-9eb7-8227af923b52\"}","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":"5","depth":4,"bounds":{"left":0.48038563,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"120","depth":4,"bounds":{"left":0.49035904,"top":0.19952115,"width":0.011968086,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"4","depth":4,"bounds":{"left":0.5043218,"top":0.19952115,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 120; $i++) {\n if ($i % 25 === 0) {\n $this->info(\"Syncing opportunity {$i}\");\n }\n $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('374720564');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands;\n\nuse Carbon\\Carbon;\nuse Carbon\\CarbonImmutable;\nuse Illuminate\\Console\\Command;\nuse InvalidArgumentException;\nuse Jiminny\\Jobs\\AutomatedReports\\RequestGenerateAskJiminnyReportJob;\nuse Jiminny\\Jobs\\AutomatedReports\\SendReportMailJob;\nuse Jiminny\\Jobs\\JobDispatcherInterface;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\AutomatedReport;\nuse Jiminny\\Models\\AutomatedReportResult;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\AutomatedReportsRepository;\nuse Jiminny\\Services\\Activity\\CrmOwnerResolver;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Services\\UserPilot\\UserPilotClient;\n\n/**\n * Class JiminnyDebugCommand\n *\n * @package Jiminny\\Console\\Commands\n */\nclass JiminnyDebugCommand extends Command\n{\n public const string FREQUENCY_DAILY = 'daily';\n public const string FREQUENCY_WEEKLY = 'weekly';\n public const string FREQUENCY_MONTHLY = 'monthly';\n public const string FREQUENCY_QUARTERLY = 'quarterly';\n public const string FREQUENCY_ONE_OFF = 'one_off';\n protected $signature = 'jiminny:debug';\n\n public function handle(\n JobDispatcherInterface $jobDispatcher,\n AutomatedReportsService $automatedReportsService,\n AutomatedReportsRepository $automatedReportsRepository,\n UserPilotClient $userPilotClient\n ): void {\n $this->rateLimit();\n exit(1);\n\n\n\n $report = AutomatedReport::find(71);\n $last = AutomatedReportResult::query()\n ->where('report_id', $report->getId())\n ->whereIn('status', [AutomatedReportResult::STATUS_DEFAULT, AutomatedReportResult::STATUS_FAILED])\n// ->where('reason', '!=', AutomatedReportResult::REASON_NOT_ENOUGH_ACTIVITIES)\n ->whereDate('created_at', CarbonImmutable::now()->toDateString())\n ->latest()\n ->first();\n\n $this->info(\"Last: {$last->getId()}\");\n\n exit(1);\n\n $user = User::find(143);\n // $count = $automatedReportsRepository->countUserReports($user);\n // $this->info(\"Count: {$count}\");\n // $count = $automatedReportsRepository->countAllUserReports($user);\n // $this->info(\"All count: {$count}\");\n\n $payload = [\n 'report_type' => 'ask_jiminny',\n 'frequency' => 'weekly',\n ];\n $userPilotClient->track($user, 'ask-jiminny-report-generated', $payload);\n\n exit(1);\n\n $now = Carbon::now()->subDay(1);\n $this->info(\"Now: {$now->toDateTimeString()}\");\n $weekStart = Carbon::getWeekStartsAt();\n $this->info(\"Now: {$weekStart}\");\n\n // $from = $now->copy()->previousWeekday()->startOfDay();\n // $to = $now->copy()->previousWeekday()->endOfDay();\n\n // $fromOld = $now->copy()->subWeeks(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subWeek()->startOfWeek();\n // $toNew = $now->copy()->subWeek()->endOfWeek();\n\n // $fromOld = $now->copy()->subMonths(1)->startOfDay();\n // $toOld = $now->copy()->subDay()->endOfDay();\n // $fromNew = $now->copy()->subMonthNoOverflow()->startOfMonth();\n // $toNew = $now->copy()->subMonthNoOverflow()->endOfMonth();\n\n $fromOld = $now->copy()->subMonths(3)->startOfDay();\n $toOld = $now->copy()->subDay()->endOfDay();\n $fromNew = $now->copy()->subQuarterNoOverflow()->startOfQuarter();\n $toNew = $now->copy()->subQuarterNoOverflow()->endOfQuarter();\n\n $this->info(\"From old: {$fromOld->toDateTimeString()}\");\n $this->info(\"To old: {$toOld->toDateTimeString()}\");\n $this->info(\"From new: {$fromNew->toDateTimeString()}\");\n $this->info(\"To new: {$toNew->toDateTimeString()}\");\n\n exit(1);\n\n $report = AutomatedReport::find(71);\n\n $job = new RequestGenerateAskJiminnyReportJob($report->getUuid());\n $jobDispatcher->dispatch($job);\n\n exit(1);\n\n\n // $this->formatDate($jobDispatcher);\n // $this->sendMail($jobDispatcher, $automatedReportsService);\n // $this->crmService();\n\n $this->getPayload($automatedReportsService);\n\n exit(1);\n }\n\n\n\n private function crmService()\n {\n $activity = Activity::find(418141);\n\n $team = Team::find(19);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n $crmService->createTranscriptNotes($activity);\n }\n\n private function sendMail(JobDispatcherInterface $jobDispatcher, AutomatedReportsService $automatedReportsService)\n {\n $reportUuid = '';\n // $report = $automatedReportsService->getReportResult($reportUuid);\n $report = AutomatedReportResult::find(275);\n $validRecipients = $automatedReportsService->getValidRecipientUsers(\n $report->getReport(),\n includeJiminny: true,\n );\n\n $recipient = $validRecipients[0];\n\n $fileName = $automatedReportsService->getReportFileName($report);\n $typeName = $report->getReport()->getCustomName()\n ?? $automatedReportsService->getReportTypeName($report);\n $teamsName = $automatedReportsService->getReportTeamsName($report);\n $periodName = $automatedReportsService->getReportPeriodName($report);\n $s3Path = $automatedReportsService->getMediaPath($report);\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$fileName ' . PHP_EOL . print_r($fileName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$typeName ' . PHP_EOL . print_r($typeName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$teamsName ' . PHP_EOL . print_r($teamsName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$periodName ' . PHP_EOL . print_r($periodName, true));\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$s3Path ' . PHP_EOL . print_r($s3Path, true));\n\n $jobDispatcher->dispatch(\n new SendReportMailJob(\n reportUuid: $report->getUuid(),\n s3Path: $s3Path,\n recipientEmail: $recipient['email'],\n recipientName: $recipient['name'] ?? null,\n fileName: $fileName,\n typeName: $typeName,\n teamsName: $teamsName,\n periodName: $periodName,\n isAskJiminny: true,\n )\n );\n\n exit(1);\n }\n\n private function formatDate(JobDispatcherInterface $jobDispatcher): void\n {\n $customName = 'Custom report name';\n // $frequency = self::FREQUENCY_DAILY;\n // $frequency = self::FREQUENCY_WEEKLY;\n $frequency = self::FREQUENCY_MONTHLY;\n // $frequency = self::FREQUENCY_QUARTERLY;\n // $frequency = self::FREQUENCY_ONE_OFF;\n $period = $this->calculateFromAndToDatePeriod($frequency);\n $from = $period['fromDate'];\n $to = $period['toDate'];\n $periodName = $this->formatReportPeriodName($frequency, $from, $to);\n $filenameSuffix = null;\n\n if ($customName) {\n if ($filenameSuffix) {\n $customName .= \" {$filenameSuffix}\";\n }\n\n $result = $this->sanitizeFileName(\"{$customName} - {$periodName}\");\n }\n\n $this->info($result);\n }\n\n public function calculateFromAndToDatePeriod(\n string $frequency,\n ?Carbon $fromDate = null,\n ?Carbon $toDate = null\n ): array {\n if ($frequency === self::FREQUENCY_ONE_OFF) {\n return [\n 'fromDate' => $fromDate,\n 'toDate' => $toDate,\n ];\n }\n\n $now = Carbon::now();\n\n return match ($frequency) {\n self::FREQUENCY_DAILY => [\n 'fromDate' => $now->copy()->subDay()->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_WEEKLY => [\n 'fromDate' => $now->copy()->subWeeks(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_MONTHLY => [\n 'fromDate' => $now->copy()->subMonths(1)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n self::FREQUENCY_QUARTERLY => [\n 'fromDate' => $now->copy()->subMonths(3)->startOfDay(),\n 'toDate' => $now->copy()->subDay()->endOfDay(),\n ],\n default => throw new InvalidArgumentException(\"Unsupported frequency: {$frequency}\"),\n };\n }\n\n private function formatReportPeriodName(string $frequency, Carbon $from, Carbon $to): string\n {\n $fromYear = $from->format('Y');\n $toYear = $to->format('Y');\n $differentYears = $fromYear !== $toYear;\n\n switch ($frequency) {\n case self::FREQUENCY_DAILY:\n return $from->format('j M Y');\n\n case self::FREQUENCY_QUARTERLY:\n // 'Jan-Mar 2025' or 'Nov 2024-Jan 2025' if years differ\n $startMonth = $from->format('M');\n $endMonth = $to->copy()->subMonth();\n $endMonthName = $endMonth->format('M');\n $endMonthYear = $endMonth->format('Y');\n\n if ($differentYears) {\n return \"{$startMonth} {$fromYear} - {$endMonthName} {$endMonthYear}\";\n }\n\n return \"{$startMonth} - {$endMonthName} {$toYear}\";\n\n case self::FREQUENCY_MONTHLY:\n // 'May 2025' - monthly reports are always within the same year\n return $from->format('M Y');\n\n case self::FREQUENCY_WEEKLY:\n // '4 - 8 Aug 2025', '27 Oct - 3 Nov 2025', or '28 Dec 2024 - 3 Jan 2025' if years differ\n $startDay = $from->format('j');\n $endDay = $to->format('j');\n $startMonth = $from->format('M');\n $endMonth = $to->format('M');\n\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n if ($startMonth !== $endMonth) {\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n return \"{$startDay} - {$endDay} {$endMonth} {$toYear}\";\n\n case self::FREQUENCY_ONE_OFF:\n // '2 May-31 May 2025' or '15 Dec 2024-15 Jan 2025' if years differ\n $startDay = $from->format('j');\n $startMonth = $from->format('M');\n $endDay = $to->format('j');\n $endMonth = $to->format('M');\n\n // If same month and year, use a format like '2-31 May 2025'\n if ($startMonth === $endMonth && ! $differentYears) {\n return \"{$startDay} - {$endDay} {$startMonth} {$toYear}\";\n }\n\n // If different years, include both years\n if ($differentYears) {\n return \"{$startDay} {$startMonth} {$fromYear} - {$endDay} {$endMonth} {$toYear}\";\n }\n\n // Same year but different months\n return \"{$startDay} {$startMonth} - {$endDay} {$endMonth} {$toYear}\";\n\n default:\n // Default format for unknown frequencies\n return $from->format('j M Y') . ' - ' . $to->format('j M Y');\n }\n }\n\n public function sanitizeFileName(string $fileName): string\n {\n return str_replace(['/', '\\\\'], '-', $fileName);\n }\n\n private function getPayload(AutomatedReportsService $automatedReportsService)\n {\n $reportResult = AutomatedReportResult::find(269);\n $automatedReport = $reportResult->getReport();\n $activityIds = [1,2,3];\n $payload = $automatedReportsService->getAskJiminnyGenerateReportPayload(\n automatedReport: $automatedReport,\n reportResult: $reportResult,\n activityIds: $activityIds,\n );\n\n \\Illuminate\\Support\\Facades\\Log::channel('custom_channel')->info('$payload ' . PHP_EOL . print_r($payload, true));\n }\n\n private function rateLimit()\n {\n $team = Team::find(2);\n $config = $team->getCrmConfiguration();\n\n $crmResolver = app(CrmOwnerResolver::class, [\n 'team' => $team,\n 'integrationAdmin' => $team->getOwner(),\n 'providerSlug' => $config->getProviderName(),\n ]);\n\n $crmService = $crmResolver->prepareCrmService();\n\n for ($i = 0 ; $i < 120; $i++) {\n if ($i % 25 === 0) {\n $this->info(\"Syncing opportunity {$i}\");\n }\n $crmService->syncOpportunity('374720564');\n $crmService->matchExactlyByEmail('374720564');\n }\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}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3651
|
134
|
19
|
2026-05-07T12:32:53.945877+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157173945_m2.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/Service.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"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":"Search Backward","depth":4,"bounds":{"left":0.7130984,"top":0.07821229,"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":"Search Forward","depth":4,"bounds":{"left":0.72174203,"top":0.07821229,"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":"Match сase","depth":4,"bounds":{"left":0.73038566,"top":0.07821229,"width":0.032247342,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"bounds":{"left":0.76263297,"top":0.07821229,"width":0.023271276,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"bounds":{"left":0.7859042,"top":0.07821229,"width":0.022938829,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"bounds":{"left":0.8088431,"top":0.08220271,"width":0.0019946808,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.97539896,"top":0.07821229,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","depth":4,"bounds":{"left":0.52859044,"top":0.016759777,"width":0.47140956,"height":0.98324025},"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","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":"7","depth":4,"bounds":{"left":0.46143618,"top":0.19952115,"width":0.0076462766,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"48","depth":4,"bounds":{"left":0.4710771,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.48337767,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","depth":4,"bounds":{"left":0.49268618,"top":0.19952115,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.5049867,"top":0.19952115,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.19792499,"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.5212766,"top":0.19792499,"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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LanguageDetection","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LiveFeed","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Locks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Math","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MediaPipeline","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MeetingBot","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MobileSettings, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Model, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Notification, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Nudge","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParagraphBreaker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ParticipantSpeech","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PartitionedCookie","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"PlaybackPage","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Playlist","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Prophet","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProphetAi, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProsperWorks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Queue","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Job","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitAware.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimitAwareWrapper.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BotsQueueConstants.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Constants.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProcessingQueueConstants.php","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Router, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Saml2","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"SCIM","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Seeder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sentry","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Serializer","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Settings","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Sidekick","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Slack","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TeamInsights, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TimeMemoryMapper, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Transcription","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"TranscriptionSummary","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Twilio","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uploader","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"UrlGenerator","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Utility","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Exceptions","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Service","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BaseRateLimiter.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"EfficientJsonParser.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ProviderRateLimiter.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"RateLimiterInstance.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Uuid","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Waveform","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Webhooks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Workflow","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Configuration","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Console, folder","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Commands","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activities","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Analytics","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Calendars","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Crm","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Hubspot","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"IntegrationApp","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Traits","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AddLayoutEntities.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AutologDelayedCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornCommandAbstract.php, abstract class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornPingCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSearchCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BullhornSessionCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CheckActivityLoggableCommand.php, final class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CleanDuplicateFieldDataCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FullSyncOpportunityCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"LogActivitiesCommand.php, final class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ManageSyncStrategyCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmObjectsCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MatchOpportunityActivitiesCommand.php, class","depth":11,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"MigrateProvider.php, class","depth":11,"on_screen":false,"role_description":"text"}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
3648
|
NULL
|
NULL
|
NULL
|
|
3650
|
133
|
13
|
2026-05-07T12:32:53.905398+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157173905_m1.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/Service.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"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":"Hubspot","depth":4,"on_screen":true,"value":"Hubspot","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":"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":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search All","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Backward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Forward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match сase","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"on_screen":true,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","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":"7","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"48","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"33","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\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Services\\Crm\\Hubspot;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Generator;\nuse GuzzleHttp\\Exception\\RequestException;\nuse Illuminate\\Support\\Facades\\Cache;\nuse InvalidArgumentException;\nuse Jiminny\\Contracts\\Repositories\\TeamRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ClientInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\FetchRelatedActivityInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\LayoutManagementInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\MatchCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\Provider\\HubspotInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityLookupInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\RemoteEntityManipulationInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SavePlaybackLinkToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SendSummaryToCrmInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SettingsInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmEntitiesInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\SyncCrmMetadataInterface;\nuse Jiminny\\Contracts\\Services\\Crm\\VerifyTaskExistsInterface;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Exceptions\\HttpNotFoundException;\nuse Jiminny\\Jobs\\Crm\\NoteObject;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Contracts\\ActivityContract;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Participant;\nuse Jiminny\\Models\\Playbook;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Repositories\\Crm\\FieldRepository;\nuse Jiminny\\Repositories\\Crm\\ProfileRepository;\nuse Jiminny\\Repositories\\ParticipantRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\BaseService;\nuse Jiminny\\Services\\Crm\\Hubspot\\Actions\\SyncArchivedProfilesAction;\nuse Jiminny\\Services\\Crm\\Hubspot\\Fields\\ValueNormalizer;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\OpportunitySyncTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncCrmEntitiesTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\SyncFieldsTrait;\nuse Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits\\WriteCrmTrait;\nuse Jiminny\\Services\\Crm\\MatchDomainByEmailInterface;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Services\\Crm\\ResolveCompanyNameByEmailTrait;\nuse Jiminny\\Utils\\PlaybackUrlBuilder;\nuse Sentry;\nuse SevenShores\\Hubspot\\Exceptions\\BadRequest;\nuse Throwable;\nuse UnexpectedValueException;\n\n/**\n * @phpstan-type CrmFieldDefinition array{\n * name: string,\n * label: string,\n * description: string,\n * type: string,\n * fieldType: string,\n * hidden: bool,\n * showCurrencySymbol: bool,\n * options: array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }\n */\nclass Service extends BaseService implements\n HubspotInterface,\n SyncCrmEntitiesInterface,\n SyncCrmMetadataInterface,\n SendSummaryToCrmInterface,\n MatchDomainByEmailInterface,\n SavePlaybackLinkToCrmInterface,\n RemoteEntityManipulationInterface,\n FetchRelatedActivityInterface,\n LayoutManagementInterface,\n SettingsInterface,\n MatchCrmEntitiesInterface,\n RemoteEntityLookupInterface,\n VerifyTaskExistsInterface\n{\n use ResolveCompanyNameByEmailTrait;\n use SyncCrmEntitiesTrait;\n use WriteCrmTrait;\n use SyncFieldsTrait;\n use OpportunitySyncTrait;\n\n private const int ENGAGEMENT_BODY_MAX_LENGTH = 65536;\n\n private const string LOG_DATE_FORMAT = 'Y-m-d H:i:s';\n private const int BATCH_UPDATE_LIMIT = 100;\n private const string TEN_SECONDLY_ROLLING_POLICY = 'TEN_SECONDLY_ROLLING';\n private const int TEN_SECONDLY_ROLLING_LIMIT = 10;\n private const string CALLS_SEARCH_ENDPOINT = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n\n private const string TYPE_NOTE = 'NOTE';\n\n private const string TYPE_MEETING = 'MEETING';\n\n private const string TYPE_CALL = 'CALL';\n\n private const string API_URL = 'https://api.hubapi.com';\n\n // NB: v1 is legacy - v3 is the newest\n private const string ENDPOINT_PIPELINES = '/crm-pipelines/v1/pipelines/';\n private const string PIPELINE_OBJECT_TYPE_DEALS = 'deals';\n\n private const int TASK_VERIFICATION_CACHE_TTL = 86400; // 1 day\n\n /**\n * @var ClientInterface|Client\n */\n protected $client;\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private SyncFieldAction $syncFieldAction;\n private PayloadBuilder $payloadBuilder;\n private SyncRelatedActivityManager $syncRelatedActivityManager;\n private SyncArchivedProfilesAction $syncArchivedProfilesAction;\n private WebhookSyncBatchProcessor $batchProcessor;\n\n public function __construct(\n Client $client,\n SyncFieldAction $syncFieldAction,\n PayloadBuilder $payloadBuilder,\n ProspectPhotoPathService $prospectPhotoPathService,\n SyncArchivedProfilesAction $syncArchivedProfilesAction,\n WebhookSyncBatchProcessor $batchProcessor,\n ) {\n parent::__construct();\n\n $this->client = $client;\n $this->syncFieldAction = $syncFieldAction;\n $this->prospectPhotoPathService = $prospectPhotoPathService;\n $this->payloadBuilder = $payloadBuilder;\n $this->syncArchivedProfilesAction = $syncArchivedProfilesAction;\n $this->batchProcessor = $batchProcessor;\n $this->opportunitySyncStrategyResolver = app(OpportunitySyncStrategyResolver::class, [\n 'client' => $this->client,\n ]);\n $this->syncRelatedActivityManager = app(SyncRelatedActivityManager::class, [\n 'client' => $this->client,\n 'payloadBuilder' => $this->payloadBuilder,\n 'logger' => $this->logger,\n ]);\n $this->crmEntityRepository = app(CrmEntityRepository::class);\n $this->dealFieldsService = app(DealFieldsService::class);\n }\n\n public function getDisplayName(): string\n {\n return 'HubSpot';\n }\n\n protected function getOAuthAccount(User $user): ?SocialAccount\n {\n // In this case, the Account Owner is always the connection for any API operations.\n $owner = $user->team->owner;\n\n return $owner->getSocialAccount(SocialAccount::PROVIDER_HUBSPOT);\n }\n\n public function getClient(): Client\n {\n /** @var Client */\n return $this->client;\n }\n\n /**\n * Convert raw field data into a format compatible with CRM APIs.\n *\n * @param bool $internal Direction of the conversion.\n * True is pulling from CRM, false normalize before sending to CRM.\n */\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string\n {\n return ValueNormalizer::normalize(\n fieldType: $fieldType,\n fieldValue: $fieldValue,\n isInbound: $internal,\n );\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultFields(string $activityType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n $defaultFields = FieldDefinitions::defaultTaskFields();\n\n // This lazy creates these fields if not already setup.\n foreach ($defaultFields as $defaultField) {\n $fields[] = $this->config->fields()->firstOrCreate($defaultField);\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityField(string $activityType): Field\n {\n /** @var Field $activityField */\n $activityField = $this->config->fields()->where([\n 'crm_provider_id' => 'activityType',\n 'object_type' => $activityType,\n ])->first();\n\n return $activityField;\n }\n\n /**\n * @inheritdoc\n */\n public function getSupportedPlaybookTypes(): array\n {\n return [Playbook::ACTIVITY_TYPE_TASK];\n }\n\n /**\n * @inheritdoc\n */\n public function getDefaultActivityLayoutFields(string $activityType, string $layoutType): array\n {\n $fields = [];\n\n if ($activityType === Playbook::ACTIVITY_TYPE_TASK) {\n // Outcome should always be provided calls/meetings.\n $fieldData = [\n [\n 'crm_provider_id' => $layoutType === Layout::TYPE_SOFTPHONE_SUMMARY ? 'disposition' : 'meetingOutcome',\n 'object_type' => Field::OBJECT_TASK,\n ],\n ];\n\n foreach ($fieldData as $data) {\n $field = $this->config->fields()->where($data)->first();\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n }\n\n return $fields;\n }\n\n public function getDealInsightsFields(): array\n {\n return FieldDefinitions::dealInsightsFields();\n }\n\n protected function getDefaultFollowupLayoutFields(string $activityType): array\n {\n $fields = [];\n $fieldRepo = app(FieldRepository::class);\n $fieldData = FieldDefinitions::followupFieldsFilter();\n\n foreach ($fieldData as $data) {\n $field = $fieldRepo->findOneConfigurationFieldByProperties($this->config, $data);\n\n // Only add the field if it is created, which it should be.\n if ($field) {\n $fields[] = $field;\n }\n }\n\n return $fields;\n }\n\n /**\n * @inheritdoc\n */\n public function syncField(Field $field): void\n {\n switch ($field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $crmField = $this->client->getInstance()->companyProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_CONTACT:\n $crmField = $this->client->getInstance()->contactProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_OPPORTUNITY:\n $crmField = $this->client->getInstance()->dealProperties()->get($field->crm_provider_id);\n\n break;\n case Field::OBJECT_TASK:\n $this->syncSingleTaskField($field);\n\n return;\n default:\n return;\n }\n\n $this->syncFieldAction->execute($field, $crmField->toArray());\n }\n\n /**\n * @param array<array{\n * id:string,\n * label:string,\n * value?:string\n * }> $options\n *\n * @throws CrmException\n *\n * @return FieldData[]\n *\n */\n public function importPicklistValues(\n Field $field,\n array $options = [['id' => '', 'label' => '', 'value' => '']],\n ): array {\n if (! empty($options[0]['id']) || ! empty($options[0]['value'])) {\n // We already have the options, no need to fetch them again\n return $this->importOptions($field, $options);\n }\n\n $options = [];\n\n switch ($field->getObjectType()) {\n case Field::OBJECT_ACCOUNT:\n $options = $this->getClient()->fetchPropertyOptions('company', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_CONTACT:\n $options = $this->getClient()->fetchPropertyOptions('contact', $field->getCrmProviderId());\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n // Hubspot has different endpoint for stages\n $options = $this->getClient()->fetchOpportunityFieldOptions($field);\n\n break;\n\n case Field::OBJECT_TASK:\n if ($field->getCrmProviderId() === 'disposition') {\n $options = $this->getClient()->fetchDispositionFieldOptions();\n } elseif (in_array($field->getCrmProviderId(), ['meetingOutcome', 'activityType'])) {\n $options = $this->getClient()->fetchMeetingOutcomeFieldOptions($field);\n }\n\n break;\n\n default:\n $this->logger->warning('Invalid object type', [\n 'object_type' => $field->getObjectType(),\n 'field_id' => $field->getId(),\n ]);\n\n throw new CrmException('Invalid object type');\n }\n\n return $this->importOptions($field, $options);\n }\n\n /**\n * @inheritdoc\n */\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage\n {\n $missingStage = null;\n\n try {\n // Use the HubSpot API client instead of the SDK crmPipelines() method\n $endpoint = self::getDealsPipelinesEndpoint();\n $pipelinesResponse = $this->client->getInstance()->getClient()->request('GET', $endpoint);\n $pipelines = $pipelinesResponse->data->results;\n } catch (RequestException|BadRequest $exception) {\n throw $exception;\n }\n\n foreach ($pipelines as $pipeline) {\n $stages = [];\n\n // We create a business process to contain the pipeline, and store all stages against it.\n $p = ResponseNormalize::normalizePipeline($pipeline);\n\n // Create/update business process for this pipeline\n $businessProcess = $this->config->businessProcesses()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'type' => BusinessProcess::TYPE_OPPORTUNITY,\n 'is_selectable' => $p['active'],\n ]);\n\n // A record type is really a clone of the business process, used to store which record uses which pipeline.\n // Create/update record type clone\n $this->config->recordTypes()->updateOrCreate([\n 'crm_provider_id' => $p['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($p['label'], 0, 150),\n 'is_selectable' => $p['active'],\n 'business_process_id' => $businessProcess->id ?? null,\n ]);\n\n // Stages - fetch all existing stages upfront to avoid N+1 queries\n $existingStages = $this->config->stages()\n ->withTrashed()\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->get()\n ->keyBy('crm_provider_id');\n\n foreach ($p['stages'] as $dealStage) {\n $s = ResponseNormalize::normalizeDealStage($dealStage);\n\n /** @var ?Stage $existingStage */\n $existingStage = $existingStages->get($s['id']);\n\n // Restore soft-deleted stages that are now active in HubSpot\n if ($existingStage?->trashed() && $s['active']) {\n $existingStage->restore();\n }\n\n // Upsert stage (updates soft-deleted records without restoring them)\n $stage = $this->config->stages()->withTrashed()->updateOrCreate([\n 'crm_provider_id' => $s['id'],\n ], [\n 'team_id' => $this->team->id,\n 'name' => mb_strimwidth($s['label'], 0, 50),\n 'label' => mb_strimwidth($s['label'], 0, 191),\n 'type' => Stage::TYPE_OPPORTUNITY,\n 'sequence' => $s['displayOrder'],\n 'is_selectable' => $s['active'],\n 'probability' => $s['probability'] * 100,\n ]);\n\n if ($missingStageName === $s['id']) {\n $missingStage = $stage;\n }\n\n $stages[] = $stage->id;\n }\n\n $businessProcess->stages()->sync($stages);\n }\n\n return $missingStage;\n }\n\n /**\n * @inheritdoc\n */\n public function syncOrganization(): void\n {\n try {\n $endpoint = 'https://api.hubapi.com/integrations/v1/me';\n $response = $this->client->getInstance()->getClient()->request('get', $endpoint);\n\n $accountData = $response->data;\n $this->config->update(['default_currency' => $accountData->currency]);\n } catch (BadRequest $e) {\n throw new CrmException('Could not sync the organization.', $e->getCode(), $e);\n }\n }\n\n /**\n * @inheritdoc\n *\n * @throws CrmException\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile\n {\n $this->syncArchivedProfilesAction->execute($this->team, $this->client, $this->config);\n\n try {\n $owners = $this->client->getOwners();\n } catch (\\HubSpot\\Client\\Crm\\Owners\\ApiException $e) {\n $this->logger->error('[HubSpot] Could not sync the profiles.', [\n 'team_id' => $this->team->getId(),\n 'reason' => $e->getMessage(),\n ]);\n\n throw new CrmException('Could not sync the profiles.', $e->getCode(), $e);\n }\n\n $profileRepository = app(ProfileRepository::class);\n $teamRepository = app(TeamRepository::class);\n\n foreach ($owners as $owner) {\n if ($owner->getArchived()) {\n // not supposed to fetch archived, but log anyway\n $this->logger->warning('[HubSpot] Found archived owner', [\n 'crm_provider_id' => $owner->getId(),\n 'email' => $owner->getEmail(),\n ]);\n\n continue;\n }\n\n $email = $owner->getEmail();\n if ($email === null) {\n continue;\n }\n\n $user = $teamRepository->findActiveTeamMemberByEmail($this->team, $email);\n\n if (! $user instanceof User) {\n continue;\n }\n\n $profile = $profileRepository->updateOrCreateProfile($user, [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $owner->getId(),\n ]);\n\n if ($userToSearch && $userToSearch->getId() === $user->getId()) {\n return $profile;\n }\n }\n\n return null;\n }\n\n private function generateNameSearchPayload(string $name, int $offset, int $limit): array\n {\n $payload = [\n 'query' => $name,\n 'sorts' => [\n [\n 'propertyName' => 'modifieddate',\n 'direction' => 'DESCENDING',\n ],\n ],\n 'properties' => [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n 'industry',\n 'name',\n 'company',\n ],\n 'limit' => $limit,\n 'after' => $offset,\n ];\n\n $this->logger->debug('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n return $payload;\n }\n\n /**\n * @inheritdoc\n */\n public function find(string $name, array $scopes): array\n {\n $count = $this->limit ?? 20;\n $offset = $this->offset ?? 0;\n\n /** @var array<int, array<string, mixed>> */\n return Cache::remember(\n key: $this->team->getId() . $name . $count . $offset,\n ttl: 300,\n callback: function () use ($name, $offset, $count): array {\n $data = [];\n\n // Use the new V3 API to find contacts based on additional fields.\n foreach (['companies', 'contacts'] as $objectType) {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/' . $objectType . '/search';\n $payload = $this->generateNameSearchPayload($name, $offset, $count);\n $type = $objectType === 'companies' ? 'account' : 'contact';\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, [\n 'json' => $payload,\n ]);\n\n // Build mapped list.\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n\n $objectName = $this->buildContactName($properties);\n\n $record = [\n 'crmId' => $object['id'],\n // Pass crmUrl to the FE, needed for success message in the extension when you log activity.\n 'crmUrl' => $this->generateProviderUrl($object['id'], $type),\n 'name' => $objectName,\n 'prospectType' => $type,\n 'phoneNumbers' => [],\n ];\n\n if ($type === 'account') {\n $record['industry'] = $properties['industry'] ?? null;\n } else {\n $record['title'] = $properties['jobtitle'] ?? null;\n $record['organization'] = $properties['company'] ?? null;\n }\n\n $countryCode = $this->buildContactCountry($properties);\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n\n // Add phone number to record.\n if (! empty($parsedNumber['phone'])) {\n $record['phoneNumbers'][] = [\n 'number' => $parsedNumber['phone'],\n 'nationalFormat' => phone_national($countryCode, $parsedNumber['phone']),\n 'type' => 'phone',\n ];\n }\n\n // Add mobile phone number to record.\n if (! empty($properties['mobilephone'])) {\n $mobileNumber = phone_e164($countryCode, $properties['mobilephone']);\n if ($mobileNumber !== null) {\n $record['phoneNumbers'][] = [\n 'number' => $mobileNumber,\n 'nationalFormat' => phone_national($countryCode, $mobileNumber),\n 'type' => 'mobile',\n ];\n }\n }\n\n $data[] = $record;\n }\n } catch (BadRequest $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->getUuid(),\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $data;\n },\n );\n }\n\n\n /**\n * @inheritdoc\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array\n {\n $data = [];\n $ownerData = [];\n $ownerId = null;\n\n if ($crmAccountId === null) {\n return $data;\n }\n\n if ($userId) {\n $profileRepository = app(ProfileRepository::class);\n $profile = $profileRepository->findProfileByUserId($this->config, $userId);\n\n $ownerId = $profile instanceof Profile ? $profile->getCrmProviderId() : null;\n }\n\n $closedStages = $this->getClosedDealStages();\n $payload = $this->payloadBuilder->generateOpportunitiesSearchPayload(\n $this->config,\n $crmAccountId,\n $closedStages,\n );\n\n $results = $this->client->getPaginatedData($payload, 'deals');\n\n foreach ($results['results'] as $object) {\n $properties = $object['properties'];\n\n $amount = null;\n if (empty($properties['amount']) === false) {\n $currency = $properties['deal_currency_code'] ?? $this->config->default_currency;\n\n // Values can contain commas and any junk so strip them.\n $value = (float) preg_replace('/[^\\d.]/', '', $properties['amount']);\n $amount = formatCurrency($value, $currency);\n }\n\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n\n if ($businessProcess === null) {\n // Import it.\n $stage = $this->importStages([Stage::TYPE_OPPORTUNITY], $properties['dealstage']);\n $businessProcess = $this->config\n ->businessProcesses()\n ->where('crm_provider_id', $properties['pipeline'])\n ->first();\n } else {\n $stage = $businessProcess\n ->stages()\n ->where('crm_provider_id', $properties['dealstage'])\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n if ($stage === null) {\n // Import it.\n $stage = $this->importStages(null, $properties['dealstage']);\n }\n }\n\n $recordType = null;\n if ($businessProcess) {\n $recordType = $businessProcess->recordTypes()->first();\n }\n\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $record = [\n 'crmId' => $object['id'],\n 'name' => $properties['dealname'] ?? 'Unknown Deal',\n 'value' => $amount,\n 'won' => $isWon,\n 'closed' => $isWon || $isLost,\n 'stage' => [\n 'id' => $stage?->getUuid() ?? '',\n 'name' => $stage?->getName() ?? '',\n ],\n ];\n\n if ($recordType) {\n $record += [\n 'recordType' => [\n 'id' => $recordType->id_string,\n 'name' => $recordType->name,\n ],\n ];\n }\n\n if ($ownerId && isset($properties['hubspot_owner_id']) && $properties['hubspot_owner_id'] === $ownerId) {\n $ownerData[] = $record;\n }\n\n $data[] = $record;\n }\n\n if (! empty($ownerData)) {\n return $ownerData;\n }\n\n return $data;\n }\n\n /**\n * @inheritdoc\n */\n public function getTasks(?string $objectType, string $objectId, ?string $opportunityId): array\n {\n $data = [];\n switch ($objectType) {\n case 'contact':\n $hsObject = 'contact';\n\n break;\n case 'account':\n $hsObject = 'company';\n\n break;\n default:\n // This is a hack to prioritise and override a contact/company with a deal.\n if ($opportunityId) {\n $hsObject = 'deal';\n $objectId = $opportunityId;\n } else {\n throw new InvalidArgumentException('Object type not supported.');\n }\n }\n\n $engagementTypes = ['meetings', 'tasks'];\n\n foreach ($engagementTypes as $engagementType) {\n $payload = $this->payloadBuilder->getLinkToTaskPayload($hsObject, $objectId, $engagementType);\n\n $this->logger->info('[HubSpot] CRM Search requested', [\n 'request' => $payload,\n ]);\n\n $engagements = $this->client->getPaginatedData($payload, $engagementType);\n\n foreach ($engagements['results'] as $engagement) {\n if ($engagementType == 'meetings') {\n $title = $engagement['properties']['hs_meeting_title'] ?? 'Scheduled meeting';\n } elseif ($engagementType == 'tasks') {\n $title = $engagement['properties']['hs_task_subject'];\n } else {\n $title = 'Scheduled meeting';\n }\n\n $data[] = [\n 'crmId' => $engagement['id'],\n 'subject' => $title,\n 'due' => $engagement['properties']['hs_timestamp'],\n 'type' => $engagement['properties']['hs_activity_type'] ?? null,\n ];\n }\n }\n\n usort($data, function ($item1, $item2) {\n return $item2['due'] <=> $item1['due'];\n });\n\n return $data;\n }\n\n /**\n * Try to find CRM Objects using email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array\n {\n $contactProperties = [\n 'email',\n 'firstname',\n 'lastname',\n 'country',\n 'phone',\n 'mobilephone',\n 'jobtitle',\n 'hubspot_owner_id',\n 'associatedcompanyid',\n 'photo',\n ];\n $contact = null;\n $account = null;\n\n try {\n $hsContact = $this->getClient()->getContactByEmail($email, $contactProperties);\n\n if ($hsContact) {\n $contact = $this->importContact($hsContact);\n $account = $contact->account;\n }\n\n $data = $this->convertCrmData($contact, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n } catch (BadRequest $e) {\n $this->logger->warning('[HubSpot] Search failed', [\n 'team_id' => $this->team->getId(),\n 'search_identifier' => $email,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return null;\n }\n\n public function getDomain(string $email): ?string\n {\n return $this->getDomainFromEmail($email);\n }\n\n /**\n * Try to find CRM objects using domain name of the email address\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByDomain(string $domain, ?int $userId = null): ?array\n {\n $companyName = $domain;\n\n // Try to find a company matching their email domain.\n $companyProperties = [\n 'country',\n 'phone',\n 'name',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'domain',\n ];\n\n try {\n $hsAccounts = $this->client\n ->getInstance()\n ->companies()\n ->searchByDomain($companyName, $companyProperties);\n } catch (Throwable $e) {\n $this->logger->info('[HubSpot] Search failed', [\n 'error' => $e->getMessage(),\n 'domain' => $domain,\n ]);\n\n return null;\n }\n\n $account = null;\n // If there are multiple accounts, don't guess, we'll ask later.\n if (\\count($hsAccounts->data->results) === 1) {\n // Persist this remote object.\n $account = $this->syncAccount($hsAccounts->data->results[0]->companyId);\n }\n\n $data = $this->convertCrmData(null, $account, $userId);\n\n return ! empty(array_filter($data)) ? $data : null;\n }\n\n /**\n * @return array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n protected function convertCrmData(?Contact $contact, ?Account $account, ?int $userId = null): array\n {\n $countryCode = null;\n if ($contact && $contact->country_code) {\n $countryCode = $contact->country_code;\n } elseif ($account && $account->country_code) {\n $countryCode = $account->country_code;\n }\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact ? $contact->crm_provider_id : null,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n // If there are multiple opportunities, don't guess, we'll ask later.\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n protected function getCacheKey(string $object, ?int $userId = null): ?string\n {\n $key = $this->team->getId() . $object;\n $keySuffix = $this->getOwnerKeySuffix($userId);\n\n return $key . $keySuffix;\n }\n\n private function getOwnerKeySuffix(?int $userId = null): string\n {\n return $userId === null ? '' : (string) $userId;\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array\n {\n if (str_contains($phone, '**')) {\n return null;\n }\n\n // trim all whitespaces if present so the lookup doesn't fail\n $phone = str_replace(' ', '', $phone);\n\n // Check if the user is internal.\n if ($this->isPhoneNumberOfTeamMember($phone)) {\n return null;\n }\n\n $response = $this->searchForPhoneNumber($phone);\n if (empty($response)) {\n return null;\n }\n\n // This would ideally importContact instead but the response type differs.\n $contact = $this->findAndSyncContact($response['results'][0]['id']);\n if (! $contact instanceof Contact) {\n return null;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account?->crm_provider_id,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n\n try {\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n } catch (Exception $e) {\n $this->logger->debug('[HubSpot] Opportunity failed to sync.', [\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n }\n\n private function isPhoneNumberOfTeamMember(string $phone): bool\n {\n $teamRepository = app(TeamRepository::class);\n $user = $teamRepository->findTeamMemberByPhone($this->team, $phone);\n\n if ($user instanceof User) {\n return true;\n }\n\n return false;\n }\n\n private function findAndSyncContact(string $crmId): ?Contact\n {\n try {\n return $this->syncContact($crmId);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'reason' => $exception->getMessage(),\n ]);\n\n return null;\n }\n }\n\n private function hasResults(array $response): bool\n {\n return isset($response['total']) && is_numeric($response['total']) && $response['total'] > 0;\n }\n\n private function searchForPhoneNumber(string $phone): array\n {\n // Normalizes the provided phone number for the API search.\n $normalizedPhone = $this->normalizePhoneNumber($phone);\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone);\n\n $this->logger->info('[HubSpot] Phone match search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($normalizedPhone, $payload);\n\n if (! $this->hasResults($response)) {\n $nationalPhone = preg_replace('/\\D/', '', phone_national(null, $phone));\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($nationalPhone);\n\n $this->logger->info('[HubSpot] Phone match national number search triggered', [\n 'phone' => $phone,\n 'nationalPhone' => $nationalPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n if (! $this->hasResults($response)) {\n $payload = $this->payloadBuilder->generatePhoneSearchPayload($normalizedPhone, true);\n\n $this->logger->info('[HubSpot] Phone match alternative search triggered', [\n 'phone' => $phone,\n 'normalizedPhone' => $normalizedPhone,\n 'payload' => $payload,\n ]);\n\n $response = $this->handlePhoneSearchRequest($phone, $payload);\n }\n\n return $this->hasResults($response) ? $response : [];\n }\n\n private function handlePhoneSearchRequest(string $phone, array $payload): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/contacts/search';\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n $endpoint,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Phone match failed', [\n 'phone' => $phone,\n 'reason' => $exception->getMessage(),\n ]);\n\n return [];\n }\n\n $this->logger->info('[HubSpot] Phone match completed', [\n 'phone' => $phone,\n 'response' => $response,\n ]);\n\n return $response->toArray();\n }\n\n private function normalizePhoneNumber(string $phone): string\n {\n return ltrim(phone_e164(null, $phone), '+0');\n }\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array\n {\n // Don't waste time searching for single character strings.\n if (\\strlen($name) <= 1) {\n return null;\n }\n\n $cacheKey = $this->getCacheKey($name, $userId);\n\n $result = Cache::remember($cacheKey, 60, function () use ($name, $userId) {\n $payload = $this->payloadBuilder->generateSearchContactsByNamePayload(\n $name,\n $this->getContactFields()\n );\n\n $hsContacts = $this->client->getPaginatedData($payload, 'contact');\n if (empty($hsContacts['results'])) {\n return false;\n }\n\n $contact = $this->importContact($hsContacts['results'][0]);\n if ($contact === null) {\n return false;\n }\n\n $account = $contact->account;\n $countryCode = $contact->country_code ?? $account->country_code ?? null;\n\n try {\n $hsOpportunities = $this->findOpportunities(\n $account ? $account->crm_provider_id : null,\n $contact->crm_provider_id,\n $userId\n );\n } catch (Exception $e) {\n $hsOpportunities = [];\n }\n\n $opportunity = null;\n $stage = null;\n if (! empty($hsOpportunities)) {\n // Persist this remote object.\n $opportunity = $this->syncOpportunity($hsOpportunities[0]['crmId']);\n $stage = $opportunity?->getStage();\n }\n\n return [\n null,\n $account,\n $opportunity,\n $contact,\n $stage,\n $countryCode,\n ];\n });\n\n return is_array($result) ? $result : null;\n }\n\n\n private function convertActivityAssociations(Activity $activity): array\n {\n return [\n 'contactIds' => $this->getParticipantsIds($activity),\n 'companyIds' => $activity->hasAccount() ? [$activity->account->crm_provider_id] : [],\n 'dealIds' => $activity->hasOpportunity() ? [$activity->opportunity->crm_provider_id] : [],\n 'ownerIds' => [],\n ];\n }\n\n private function getParticipantsIds(Activity $activity): array\n {\n $attendees = [];\n\n $participantRepository = app(ParticipantRepository::class);\n $participants = $participantRepository->getParticipantsWhoEnteredMeeting($activity);\n foreach ($participants as $participant) {\n if ($participant->user_id || $participant->isCoach()) {\n continue;\n }\n\n $contact = $participant->contact()->first();\n if ($contact && $contact->crm_provider_id) {\n $attendees[] = $contact->crm_provider_id;\n } else {\n if (! empty($participant->name)) {\n $attendeeData = $this->fetchMissingAttendeeInfo($participant);\n }\n if (! empty($attendeeData['id'])) {\n $attendees[] = $attendeeData['id'];\n }\n }\n }\n\n if ($activity->hasContact()) {\n $attendees[] = $activity->contact->crm_provider_id;\n }\n\n return array_unique($attendees);\n }\n\n private function fetchMissingAttendeeInfo(Participant $participant): array\n {\n // Check if we need to look inside an account context.\n $activity = $participant->getActivity();\n $companyId = $activity->hasAccount() ? $activity->getAccount()->crm_provider_id : null;\n\n // First check the local data.\n /** @var Contact[] $contacts */\n $contacts = $this->team->contacts()\n ->with('account')\n ->where('name', $participant->name)\n ->whereNotNull('email')\n ->get();\n\n foreach ($contacts as $contact) {\n // If we have a company in scope, check the contact is associated to it.\n if (\n $companyId !== null\n && ($contact->account_id === null || $companyId !== $contact->account->crm_provider_id)\n ) {\n continue;\n }\n\n return [\n 'id' => $contact->crm_provider_id,\n 'email' => $contact->email,\n ];\n }\n\n $payload = $this->generateNameSearchPayload($participant->name, 0, 20);\n\n try {\n $response = $this->client->getNewInstance()->crm()->contacts()->searchApi()->doSearch($payload);\n\n // TODO add some logic to choose the most suitable contact if multiple\n foreach ($response['results'] as $object) {\n $properties = $object['properties'];\n if (empty($object['properties']) === false) {\n // Check the company matches the contact.\n // Todo: Move this check inside the API search.\n if ($companyId !== null && $companyId !== $properties['associatedcompanyid']) {\n continue;\n }\n\n return [\n 'id' => $object['id'],\n 'email' => $properties['email'],\n ];\n }\n }\n } catch (Exception $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Search failed', [\n 'teamId' => $this->team->id_string,\n 'request' => $payload,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n return [];\n }\n\n /**\n * Store transcripts as note engagement.\n *\n * @throws Exception\n */\n public function createTranscriptNotes(Activity $activity): void\n {\n // For HS no need to check if Crm profile - Log Notes field is enabled\n // We only check if store_transcript toggle is enabled on crm profile.\n $engagement = [\n 'active' => true,\n 'ownerId' => $this->profile->crm_provider_id,\n 'timestamp' => $activity->created_at->tz($activity->user->timezone)->getTimestamp() * 1000,\n 'type' => 'NOTE',\n ];\n\n // Generate activity transcription.\n $transcriptionData = $this->generateTranscription($activity);\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $transcripts = mb_strimwidth($transcriptionData, 0, static::ENGAGEMENT_BODY_MAX_LENGTH);\n\n $metadata = [\n 'body' => $transcripts,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsEngagement = $this->client\n ->getInstance()\n ->engagements()\n ->create($engagement, $associations, $metadata);\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $noteId = $hsEngagement->data->engagement->id;\n\n // Store crm logged id in transcription.\n $transcription = $activity->getTranscription();\n $transcription->crm_activity_id = $noteId;\n $transcription->save();\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void\n {\n $payload = [\n 'properties' => $data,\n ];\n\n try {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n $this->client->getNewInstance()->crm()->deals()->basicApi()->update($objectId, $payload);\n\n break;\n case FieldData::OBJECT_CONTACT:\n $this->client->getNewInstance()->crm()->contacts()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_ACCOUNT:\n $this->client->getNewInstance()->crm()->companies()->basicApi()->update($objectId, $payload);\n\n break;\n\n case FieldData::OBJECT_TASK:\n // Endpoint for Engagements not ready\n $engagements = [\n 'type' => 'TASK',\n ];\n $metadata = $data;\n $this->client->getInstance()->engagements()->update($objectId, $engagements, $metadata);\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $objectId],\n $metadata,\n );\n\n break;\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $apiException) {\n $errorMessage = $apiException->getMessage();\n if ($apiException->getResponseBody()) {\n $responseBody = json_decode($apiException->getResponseBody(), true, 512, JSON_THROW_ON_ERROR);\n $errorMessage = $responseBody['message'] ?? $apiException->getMessage();\n }\n\n $this->logger->error(\n '[HubSpot] Update record failed',\n [\n 'objectType' => $objectType,\n 'objectId' => $objectId,\n 'payload' => $payload,\n 'reason' => $errorMessage,\n 'team' => $this->team->getUuid(),\n ]\n );\n\n throw new CrmException($errorMessage);\n }\n }\n\n /*\n * @inheritdoc\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array\n {\n switch ($objectType) {\n case FieldData::OBJECT_OPPORTUNITY:\n return $this->client->getInstance()->deals()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_CONTACT:\n return $this->client->getInstance()->contacts()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_ACCOUNT:\n return $this->client->getInstance()->companies()->getById($objectId)->toArray();\n\n case FieldData::OBJECT_TASK:\n return $this->client->getInstance()->engagements()->get($objectId)->toArray();\n\n default:\n throw new UnexpectedValueException('Unsupported object type \"' . $objectType . '\"');\n }\n }\n\n /**\n * @throws BadRequest\n * @throws CrmException\n */\n public function updateStage($crmObject, Stage $stage): void\n {\n $payload = [\n 'properties' => [\n [\n 'name' => 'dealstage',\n 'value' => $stage->crm_provider_id,\n ],\n ],\n ];\n\n try {\n $this->client->getInstance()->deals()->update($crmObject->crm_provider_id, $payload);\n } catch (BadRequest $badRequest) {\n if ($badRequest->getCode() === 403) {\n throw new CrmException(\n \"Sorry, you don't have permission to update this stage.\",\n $badRequest->getCode(),\n $badRequest,\n );\n }\n\n $this->logger->warning('[HubSpot] Stage update failed', [\n 'dealId' => $crmObject->crm_provider_id,\n 'payload' => $payload,\n 'message' => $badRequest->getMessage(),\n ]);\n\n throw $badRequest;\n }\n }\n\n public function generateProviderUrl(string $providerId, string $objectType): ?string\n {\n $url = null;\n $baseUrl = 'https://app.hubspot.com/contacts/' . $this->config->crm_provider_id . '/';\n\n switch ($objectType) {\n case 'account':\n $url = $baseUrl . 'company/' . $providerId;\n\n break;\n\n case 'contact':\n $url = $baseUrl . 'contact/' . $providerId;\n\n break;\n\n case 'opportunity':\n $url = $baseUrl . 'deal/' . $providerId;\n\n break;\n\n case 'task':\n case 'activity':\n return null;\n\n // This should not be deep-linked as per JMNY-3934.\n //$url = $baseUrl.'tasks/list/view/all/?taskId='.$providerId;\n break;\n }\n\n return $url;\n }\n\n public function searchCalls(Carbon $from, Carbon $to, string $activityProvider): array\n {\n $this->logger->info('[HubSpot] Search calls', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $calls = [];\n $page = 1;\n\n do {\n try {\n $payload = $this->payloadBuilder->generateGetCallsPayload($from, $to, $activityProvider, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n $calls = array_merge($calls, $responseResults);\n $page++;\n } while (! empty($responseResults));\n\n return $calls;\n }\n\n public function searchCallsForPeriodByPage(Carbon $from, Carbon $to, int $page, bool $retry = true)\n {\n try {\n $payload = $this->payloadBuilder->generateSearchCallsByPeriodPayload($from, $to, $page);\n $response = $this->client->getInstance()->getClient()->request(\n 'POST',\n self::CALLS_SEARCH_ENDPOINT,\n ['json' => ($payload)],\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search calls for period failed', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallsForPeriodByPage($from, $to, $page, false);\n }\n $response = null;\n }\n\n return $response;\n }\n\n public function searchCallsForPeriod(Carbon $from, Carbon $to): Generator\n {\n $this->logger->info('[HubSpot] Search calls for period', [\n 'from' => $from->format(self::LOG_DATE_FORMAT),\n 'to' => $to->format(self::LOG_DATE_FORMAT),\n ]);\n\n $page = 1;\n\n do {\n $response = $this->searchCallsForPeriodByPage($from, $to, $page);\n\n $responseResults = empty($response['results']) ? [] : $response['results'];\n\n $associationContacts = $this->getAssociationDataForCollection($responseResults, 'calls', 'contacts');\n $associationCompanies = $this->getAssociationDataForCollection($responseResults, 'calls', 'companies');\n $associationDeals = $this->getAssociationDataForCollection($responseResults, 'calls', 'deals');\n\n foreach ($responseResults as $call) {\n $call['associations'] = [\n 'contacts' => $this->importAssociationData($call, $associationContacts),\n 'companies' => $this->importAssociationData($call, $associationCompanies),\n 'deals' => $this->importAssociationData($call, $associationDeals),\n ];\n\n yield $call;\n }\n $page++;\n } while (! empty($responseResults));\n }\n\n public function getCall(string $callId): array\n {\n $this->logger->info('[HubSpot] Get call', [\n 'call_id' => $callId,\n ]);\n\n $searchAttributes = $this->payloadBuilder->getSearchCallAttributes();\n $endpoint = sprintf(\n 'https://api.hubapi.com/crm/v3/objects/calls/%s',\n $callId,\n );\n\n try {\n $response = $this->client->getInstance()->getClient()->request(\n 'GET',\n $endpoint,\n [],\n sprintf(\n 'properties=%s&associations=contacts,companies,deals',\n implode(',', $searchAttributes),\n ),\n );\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Get call failed', [\n 'call_id' => $callId,\n 'reason' => $exception->getMessage(),\n ]);\n $response = null;\n }\n\n return empty($response) ? [] : $response->toArray();\n }\n\n public function bulkAddPlaybackURLToDescription(array $crmUpdateData): array\n {\n $crmUpdateBatches = array_chunk($crmUpdateData, self::BATCH_UPDATE_LIMIT);\n\n $updatedCrmIds = [];\n\n foreach ($crmUpdateBatches as $crmBatch) {\n $payload = $this->payloadBuilder->generatePlaybackAddUrlBatchPayload($crmBatch);\n $updateSuccess = $this->bulkAddPlaybackURLToDescriptionRequest($payload);\n if ($updateSuccess) {\n $updatedCrmIds = array_merge($updatedCrmIds, array_column($crmBatch, 'crm_id'));\n }\n }\n\n return $updatedCrmIds;\n }\n\n private function bulkAddPlaybackURLToDescriptionRequest(array $payload, bool $retry = true): bool\n {\n try {\n $this->client->getNewInstance()->crm()->objects()->batchApi()->update('calls', $payload);\n\n return true;\n } catch (\\HubSpot\\Client\\Crm\\Objects\\ApiException $e) {\n $response = json_decode($e->getResponseBody(), true);\n $retryAfter =\n isset($response['policyName'])\n && $response['policyName'] == self::TEN_SECONDLY_ROLLING_POLICY\n ? self::TEN_SECONDLY_ROLLING_LIMIT\n : 1;\n } catch (Exception $e) {\n $retryAfter = 1;\n }\n\n $this->logger->warning('[HubSpot] Bulk add playback url to CRM failed', [\n 'reason' => $e->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep($retryAfter);\n\n return $this->bulkAddPlaybackURLToDescriptionRequest($payload, false);\n }\n\n return false;\n }\n\n /**\n * Sometimes we have secondly rate limit error, then retry request after 1 second\n */\n public function searchCallByRecordingURLToken(string $playbackURLToken, bool $retry = true): array\n {\n $endpoint = 'https://api.hubapi.com/crm/v3/objects/calls/search';\n $payload = $this->payloadBuilder->generateSearchCallByTokenPayload($playbackURLToken);\n\n $this->logger->info('[HubSpot] CRM Search by playback URL token requested', [\n 'request' => $payload,\n ]);\n\n try {\n $response = $this->client->getInstance()->getClient()->request('POST', $endpoint, ['json' => ($payload)]);\n } catch (Exception $exception) {\n $this->logger->info('[HubSpot] Search by playback URL token failed', [\n 'playbackURLToken' => $playbackURLToken,\n 'reason' => $exception->getMessage(),\n 'retry' => $retry,\n ]);\n\n if ($retry) {\n sleep(1);\n\n return $this->searchCallByRecordingURLToken($playbackURLToken, false);\n }\n\n return [];\n }\n\n return empty($response['results']) ? [] : $response['results'][0];\n }\n\n /**\n * Generate transcription for the activity.\n */\n private function generateTranscription(Activity $activity): string\n {\n if (! $this->config->store_transcript) {\n // If sending transcription to activity toggle is disabled\n return '';\n }\n\n $transcriptionSegments = $this->transcriptionService->findTranscriptionByActivity($activity);\n\n if ($transcriptionSegments->isEmpty()) {\n return '';\n }\n\n $transcription = sprintf(\n '<p><strong>Transcript for %s</strong></p><p></p>',\n $activity->title ?? $activity->activity_title,\n );\n\n $roomOwnerParticipant = $activity->findParticipantRoomOwner();\n $roomOwnerParticipantId = $roomOwnerParticipant !== null\n ? $roomOwnerParticipant->getId()\n : null;\n\n\n $transcription .= $transcriptionSegments\n ->map(static function (array $transcriptionSegment) use ($roomOwnerParticipantId): string {\n $isOrganiser = $roomOwnerParticipantId === $transcriptionSegment['participantId']\n && $roomOwnerParticipantId !== null;\n $transcriptColor = $isOrganiser ? '#000000' : '#f0415a';\n\n return sprintf(\n '<span style=\"color: %s;\">%s | </span>%s',\n $transcriptColor,\n $transcriptionSegment['formattedStartsAt'],\n $transcriptionSegment['transcript'],\n );\n })\n ->implode('<br />');\n\n return $transcription;\n }\n\n /**\n * @param array<array{\n * id: string,\n * label: string,\n * value?: string,\n * }> $options\n *\n * @return FieldData[]\n */\n private function importOptions(Field $field, array $options): array\n {\n $fieldValues = [];\n $values = [];\n $sequence = 0;\n\n foreach ($options as $option) {\n $values[] = [\n 'value' => $option['value'] ?? $option['id'],\n 'label' => substr($option['label'], 0, 255),\n 'sequence' => $sequence++,\n ];\n }\n\n $fieldsToPurge = $field->values()->get()->pluck('value')->toArray();\n\n foreach ($values as $value) {\n $value['value'] = substr($value['value'], 0, 255);\n $fieldValues[] = $field->values()->updateOrCreate([\n 'value' => $value['value'],\n ], $value);\n\n // Remove this value from the ones we are going to purge.\n if (($key = array_search($value['value'], $fieldsToPurge, false)) !== false) {\n unset($fieldsToPurge[$key]);\n }\n }\n\n // Delete the old values that are no longer used.\n $field->values()->whereIn('value', $fieldsToPurge)->delete();\n\n return $fieldValues;\n }\n\n public function saveTranscriptionSummaryAsNote(\n ActivityContract $activity,\n string $title,\n string $body,\n ?string $objectId,\n ?NoteObject $noteObject = null,\n ): ?string {\n if ($noteObject === null || $objectId === null) {\n return null;\n }\n\n /** @var User $user */\n $user = $activity->getUser();\n\n $profile = $this->assignCrmOwner($user, $activity);\n if (! $profile instanceof Profile) {\n return null;\n }\n\n $timestamp = Carbon::now($user->getTimezone())->getTimestamp() * 1000;\n $engagement = [\n 'active' => true,\n 'ownerId' => $profile->getAttribute('crm_provider_id'),\n 'timestamp' => $timestamp,\n 'type' => 'NOTE',\n ];\n\n // Truncate Notes with max notes length because transcription text could be very long.\n $body = mb_strimwidth($body, 0, self::ENGAGEMENT_BODY_MAX_LENGTH);\n $metadata = [\n 'body' => $body,\n ];\n\n $associations = $this->convertActivityAssociations($activity);\n\n try {\n $hsActivityId = $this->client->createNote(\n body: $body,\n ownerId: $profile->getCrmProviderId(),\n timestamp: $timestamp,\n objectId: $objectId,\n noteObject: $noteObject,\n );\n\n $this->logCrmEngagementManipulation(self::ACTION_CREATE, $engagement, $metadata, $associations);\n\n $this->logger->info('[HubSpot] Saving Transcription Summary as Note', [\n 'activity' => $activity->getUuid(),\n 'crmActivity' => $hsActivityId,\n ]);\n\n return $hsActivityId;\n } catch (Exception $e) {\n Sentry::captureException($e);\n }\n\n return null;\n }\n\n public function attachSummaryToActivity(ActivityContract $activity, string $summaryTitle, string $summaryContents): bool\n {\n $this->logger->info('[HubSpot] Attaching summary to activity', [\n 'activity' => $activity->getUuid(),\n 'summary_content' => $summaryContents,\n ]);\n\n if (! $activity instanceof Activity) {\n throw new InvalidArgumentException('Expected instance of Activity');\n }\n\n $summary = '<p><strong>' . $summaryTitle . '</strong></p>';\n $summary .= '<p>' . $summaryContents . '</p>';\n $metadata = $this->buildMetadataForSummaryUpdate($activity, $summary);\n\n try {\n $type = $this->matchActivityEngagementType($activity);\n $engagement = ['type' => $type];\n\n $this->client->updateEngagement($activity->getCrmProviderId(), $engagement, $metadata);\n } catch (Exception $e) {\n $this->logger->warning('[HubSpot] Update summary failed', [\n 'activity' => $activity->getUuid(),\n 'reason' => $e->getMessage(),\n ]);\n\n return false;\n }\n\n $this->logCrmEngagementManipulation(\n self::ACTION_UPDATE,\n ['crmId' => $activity->getCrmProviderId()],\n $metadata,\n );\n\n return true;\n }\n\n private function buildMetadataForSummaryUpdate(Activity $activity, string $summary): array\n {\n $descriptionField = $activity->getType() === Activity::TYPE_CONFERENCE ? 'internalMeetingNotes' : 'body';\n $engagement = $this->client->getEngagementData($activity->getCrmProviderId());\n // Meeting without internalMeetingNotes might mean it just does not have any notes;\n $description = $engagement['metadata'][$descriptionField] ?? null;\n\n if (empty($description)) {\n $data = $summary;\n } else {\n // avoid playbook url link to Jiminny being sent twice in the activity description\n $targetUrl = PlaybackUrlBuilder::build($activity);\n\n if (str_contains($description, $targetUrl)) {\n $jiminnyUrl = '<p><a href=\"' . $targetUrl . '\" title=\"Play at Jiminny\">Play at Jiminny</a></p>';\n $summary = str_replace($jiminnyUrl, '', $summary);\n\n $this->logger->info('[HubSpot] Summary modified', [\n 'activity' => $activity->getUuid(),\n 'target_url' => $jiminnyUrl,\n 'modified_summary_content' => $summary,\n ]);\n }\n\n $data = $description . '<p></p>' . $summary;\n }\n\n return [\n $descriptionField => $data,\n ];\n }\n\n public function fetchAndAssociateRelatedActivity(Activity $activity): ?Activity\n {\n return $this->syncRelatedActivityManager->fetchAndAssociateRelatedActivity($activity);\n }\n\n public function fetchRelatedActivity(Activity $activity): array\n {\n return [];\n }\n\n public function getDealsInBulk(array $dealIds): array\n {\n $payload = $this->payloadBuilder->getDealsInBulkPayload($dealIds);\n\n return $this->client->getPaginatedData($payload, 'deals');\n }\n\n /**\n * Extract deal IDs from HubSpot search response.\n *\n * @param array $hubspotResponse The raw HubSpot search API response.\n * @param bool $includeArchived Whether to include archived deals (default: false).\n *\n * @return string[] Array of deal IDs as strings.\n */\n public function extractDealIds(array $hubspotResponse, bool $includeArchived = false): array\n {\n if (empty($hubspotResponse['results'])) {\n return [];\n }\n\n return array_values(\n array_map(\n fn ($deal) => $deal['id'],\n array_filter(\n $hubspotResponse['results'],\n fn ($deal) => $includeArchived || empty($deal['archived'])\n )\n )\n );\n }\n\n public function matchActivityEngagementType(Activity $activity): string\n {\n return match ($activity->getType()) {\n Activity::TYPE_CONFERENCE => self::TYPE_MEETING,\n Activity::TYPE_SOFTPHONE, Activity::TYPE_SOFTPHONE_INBOUND => self::TYPE_CALL,\n default => self::TYPE_NOTE,\n };\n }\n\n private function assignCrmOwner(User $user, ActivityContract $activity): ?Profile\n {\n $profile = $user->getProfile();\n if ($profile instanceof Profile) {\n return $profile;\n }\n\n $this->logger->info('[HubSpot] Unable to save summary. No profile', [\n 'activity' => $activity->getUuid(),\n ]);\n\n return null;\n }\n\n private static function getDealsPipelinesEndpoint(): string\n {\n return self::API_URL . self::ENDPOINT_PIPELINES . self::PIPELINE_OBJECT_TYPE_DEALS;\n }\n\n public function verifyTaskExists(Activity $activity): bool\n {\n $crmProviderId = $activity->getCrmProviderId();\n $cacheKey = \"crm_task_exists:{$this->config->getId()}:$crmProviderId\";\n\n return Cache::remember($cacheKey, self::TASK_VERIFICATION_CACHE_TTL, function () use ($crmProviderId) {\n try {\n $engagement = $this->client->getEngagementData($crmProviderId);\n\n return ! empty($engagement);\n } catch (HttpNotFoundException|BadRequest) {\n // Engagement not found in CRM - this is expected and permanent\n $this->logger->info('[Hubspot] Engagement not found during verification', [\n 'engagement_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return false;\n }\n // Let other exceptions (network errors, rate limits, etc.) bubble up for retry\n });\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},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivitySearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiActivityType, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiAutomation, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AiCallScoring, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnything","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Dtos","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Events","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskAnythingPromptService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"HistoryService.php, class","depth":10,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AskJiminnyAi","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"AWS","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"BillingManagement","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Cache","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CoachingFeedback","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Country, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"CustomerApi, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Database, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Datadog, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DateTime, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealInsights, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"DealRisks","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ElasticSearch","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Eloquent","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encoding","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Encryption","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ES","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Faker","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FeatureFlags","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FFMpeg","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"FileSystem","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gecko","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Gong","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"GuzzleHttp","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"KeyPoints","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Kiosk","depth":9,"on_screen":false,"role_description":"text"}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3649
|
133
|
12
|
2026-05-07T12:32:48.918948+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157168918_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Search
MatchCrmEntitiesInterface \Jiminny\Contra Search
MatchCrmEntitiesInterface \Jiminny\Contracts\Services\Crm, public abstract method
BullhornService \Jiminny\Services\Crm\Bullhorn, public method
Service \Jiminny\Services\Crm\Close, public method
Service \Jiminny\Services\Crm\Copper, public method
Service \Jiminny\Services\Crm\Dummy, public method
Service \Jiminny\Services\Crm\Hubspot, public method
MatchProspectsTrait \Jiminny\Services\Crm\IntegrationApp\ServiceTraits, public method
Service \Jiminny\Services\Crm\Pipedrive, public method
Service \Jiminny\Services\Crm\Salesforce, public method
Choose subclass of matchExactlyByEmail
Open in Find Tool Window...
|
[{"role":"AXTextField","text [{"role":"AXTextField","text":"Search","depth":1,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"MatchCrmEntitiesInterface \\Jiminny\\Contracts\\Services\\Crm, public abstract method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"BullhornService \\Jiminny\\Services\\Crm\\Bullhorn, public method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Close, public method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Copper, public method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Dummy, public method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Hubspot, public method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchProspectsTrait \\Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits, public method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Pipedrive, public method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Salesforce, public method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Choose subclass of matchExactlyByEmail","depth":1,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":1,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Open in Find Tool Window","depth":1,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5983560293935804923
|
7798511394381191943
|
click
|
accessibility
|
NULL
|
Search
MatchCrmEntitiesInterface \Jiminny\Contra Search
MatchCrmEntitiesInterface \Jiminny\Contracts\Services\Crm, public abstract method
BullhornService \Jiminny\Services\Crm\Bullhorn, public method
Service \Jiminny\Services\Crm\Close, public method
Service \Jiminny\Services\Crm\Copper, public method
Service \Jiminny\Services\Crm\Dummy, public method
Service \Jiminny\Services\Crm\Hubspot, public method
MatchProspectsTrait \Jiminny\Services\Crm\IntegrationApp\ServiceTraits, public method
Service \Jiminny\Services\Crm\Pipedrive, public method
Service \Jiminny\Services\Crm\Salesforce, public method
Choose subclass of matchExactlyByEmail
Open in Find Tool Window...
|
3647
|
NULL
|
NULL
|
NULL
|
|
3648
|
134
|
18
|
2026-05-07T12:32:48.855495+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157168855_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Search
MatchCrmEntitiesInterface \Jiminny\Contra Search
MatchCrmEntitiesInterface \Jiminny\Contracts\Services\Crm, public abstract method
BullhornService \Jiminny\Services\Crm\Bullhorn, public method
Service \Jiminny\Services\Crm\Close, public method
Service \Jiminny\Services\Crm\Copper, public method
Service \Jiminny\Services\Crm\Dummy, public method
Service \Jiminny\Services\Crm\Hubspot, public method
MatchProspectsTrait \Jiminny\Services\Crm\IntegrationApp\ServiceTraits, public method
Service \Jiminny\Services\Crm\Pipedrive, public method
Service \Jiminny\Services\Crm\Salesforce, public method
Choose subclass of matchExactlyByEmail
Open in Find Tool Window...
|
[{"role":"AXTextField","text [{"role":"AXTextField","text":"Search","depth":1,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"MatchCrmEntitiesInterface \\Jiminny\\Contracts\\Services\\Crm, public abstract method","depth":4,"bounds":{"left":0.11269947,"top":0.49321628,"width":0.20412233,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"BullhornService \\Jiminny\\Services\\Crm\\Bullhorn, public method","depth":4,"bounds":{"left":0.11269947,"top":0.51077414,"width":0.20412233,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Close, public method","depth":4,"bounds":{"left":0.11269947,"top":0.528332,"width":0.20412233,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Copper, public method","depth":4,"bounds":{"left":0.11269947,"top":0.54588985,"width":0.20412233,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Dummy, public method","depth":4,"bounds":{"left":0.11269947,"top":0.5634477,"width":0.20412233,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Hubspot, public method","depth":4,"bounds":{"left":0.11269947,"top":0.5810056,"width":0.20412233,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchProspectsTrait \\Jiminny\\Services\\Crm\\IntegrationApp\\ServiceTraits, public method","depth":4,"bounds":{"left":0.11269947,"top":0.59856343,"width":0.20412233,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Pipedrive, public method","depth":4,"bounds":{"left":0.11269947,"top":0.6161213,"width":0.20412233,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Service \\Jiminny\\Services\\Crm\\Salesforce, public method","depth":4,"bounds":{"left":0.11269947,"top":0.63367915,"width":0.20412233,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Choose subclass of matchExactlyByEmail","depth":1,"bounds":{"left":0.116023935,"top":0.4668795,"width":0.18816489,"height":0.026336791},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":1,"bounds":{"left":0.30551863,"top":0.47007182,"width":0.0013297872,"height":0.019952115},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Open in Find Tool Window","depth":1,"bounds":{"left":0.3068484,"top":0.47007182,"width":0.005319149,"height":0.019952115},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5983560293935804923
|
7798511394381191943
|
click
|
accessibility
|
NULL
|
Search
MatchCrmEntitiesInterface \Jiminny\Contra Search
MatchCrmEntitiesInterface \Jiminny\Contracts\Services\Crm, public abstract method
BullhornService \Jiminny\Services\Crm\Bullhorn, public method
Service \Jiminny\Services\Crm\Close, public method
Service \Jiminny\Services\Crm\Copper, public method
Service \Jiminny\Services\Crm\Dummy, public method
Service \Jiminny\Services\Crm\Hubspot, public method
MatchProspectsTrait \Jiminny\Services\Crm\IntegrationApp\ServiceTraits, public method
Service \Jiminny\Services\Crm\Pipedrive, public method
Service \Jiminny\Services\Crm\Salesforce, public method
Choose subclass of matchExactlyByEmail
Open in Find Tool Window...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3647
|
133
|
11
|
2026-05-07T12:32:47.302054+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157167302_m1.jpg...
|
PhpStorm
|
faVsco.js – ServiceInterface.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"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":"Hubspot","depth":4,"on_screen":true,"value":"Hubspot","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":"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":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search All","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Backward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Forward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match сase","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"on_screen":true,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","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":"AXTextArea","text":"<?php\n\nnamespace Jiminny\\Contracts\\Services\\Crm;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\n\ninterface ServiceInterface\n{\n public function getDisplayName(): string;\n\n public function setUser(User $user): void;\n\n public function createTranscriptNotes(Activity $activity): void;\n\n /**\n * @param string $objectId\n * @param ?string $objectType\n *\n * @return array\n */\n public function parseRecords(string $objectId, ?string $objectType = null): array;\n\n /**\n * @param string $activityType\n *\n * @return array\n */\n public function getDefaultFields(string $activityType): array;\n\n /**\n * @param string $activityType\n *\n * @return Field\n */\n public function getDefaultActivityField(string $activityType): Field;\n\n /**\n * @return array\n */\n public function getSupportedPlaybookTypes(): array;\n\n public function buildLayout(Layout $layout, ?string $activityType): void;\n\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string;\n\n /**\n * Update the type, label etc. for a field.\n *\n * @param Field $field\n *\n * @return void\n */\n public function syncField(Field $field): void;\n\n /**\n * Import all picklist values.\n *\n * @param Field $field\n *\n * @return array\n */\n public function importPicklistValues(Field $field): array;\n\n // Sync multiple records.\n public function syncContacts(Carbon $since, ?Carbon $to = null): int;\n\n public function syncOpportunities(array $parameters, ?string $strategy = null): int;\n\n public function syncAccounts(Carbon $since, ?Carbon $to = null): int;\n\n public function syncLeads(Carbon $since, ?Carbon $to = null, ?string $crmProfileId = null): int;\n\n // Sync single records.\n public function syncContact(string $crmId): ?Contact;\n\n public function syncOpportunity(string $crmId): ?Opportunity;\n\n public function syncAccount(string $crmId): ?Account;\n\n public function syncLead(string $crmId): ?Lead;\n\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage;\n\n public function syncOrganization(): void;\n\n /**\n * Text search for CRM Objects.\n *\n * @param string $name\n * @param array $scopes\n *\n * @return array\n */\n public function find(string $name, array $scopes): array;\n\n /**\n * Get the Opportunities for an Account.\n *\n * @param null|string $crmAccountId\n * @param null|string $crmContactId\n *\n * @return array\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array;\n\n /**\n * Get the Tasks for an object.\n *\n * @param string $objectType\n * @param string $objectId\n * @param string|null $opportunityId\n *\n * @return array\n */\n public function getTasks(string $objectType, string $objectId, ?string $opportunityId): array;\n\n /**\n * Try to find email address in CRM service\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array;\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array;\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array;\n\n /**\n * @param Activity $activity\n *\n * @return Activity\n */\n public function saveActivity(Activity $activity): Activity;\n\n /**\n * @param Activity $activity\n * @param array $fields\n *\n * @return null|string\n */\n public function saveFollowupActivity(Activity $activity, array $fields): ?string;\n\n /**\n * @param $crmObject\n * @param Stage $stage\n */\n public function updateStage($crmObject, Stage $stage): void;\n\n /**\n * @param User|null $userToSearch\n *\n * @return Profile|null\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile;\n\n /**\n * @param string $providerId\n * @param string $objectType\n *\n * @return null|string\n */\n public function generateProviderUrl(string $providerId, string $objectType): ?string;\n\n /**\n * @param string $objectType\n * @param string $objectId\n * @param array $data\n * @param array $headers\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void;\n\n /**\n * @param string $objectType\n * @param string $objectId\n * @param array $fields\n *\n * @return array\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array;\n\n public function getConfiguration(): Configuration;\n\n public function setConfiguration(Configuration $config): void;\n\n /** @return array<int, array<string, string>> */\n public function getDealInsightsFields(): array;\n\n /** A most useless method */\n public function getMinimumApiVersion(): int|float|string;\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Contracts\\Services\\Crm;\n\nuse Carbon\\Carbon;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Configuration;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\Profile;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Opportunity;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\User;\n\ninterface ServiceInterface\n{\n public function getDisplayName(): string;\n\n public function setUser(User $user): void;\n\n public function createTranscriptNotes(Activity $activity): void;\n\n /**\n * @param string $objectId\n * @param ?string $objectType\n *\n * @return array\n */\n public function parseRecords(string $objectId, ?string $objectType = null): array;\n\n /**\n * @param string $activityType\n *\n * @return array\n */\n public function getDefaultFields(string $activityType): array;\n\n /**\n * @param string $activityType\n *\n * @return Field\n */\n public function getDefaultActivityField(string $activityType): Field;\n\n /**\n * @return array\n */\n public function getSupportedPlaybookTypes(): array;\n\n public function buildLayout(Layout $layout, ?string $activityType): void;\n\n public function normalizeValue(string $fieldType, string $fieldValue, bool $internal = false): string;\n\n /**\n * Update the type, label etc. for a field.\n *\n * @param Field $field\n *\n * @return void\n */\n public function syncField(Field $field): void;\n\n /**\n * Import all picklist values.\n *\n * @param Field $field\n *\n * @return array\n */\n public function importPicklistValues(Field $field): array;\n\n // Sync multiple records.\n public function syncContacts(Carbon $since, ?Carbon $to = null): int;\n\n public function syncOpportunities(array $parameters, ?string $strategy = null): int;\n\n public function syncAccounts(Carbon $since, ?Carbon $to = null): int;\n\n public function syncLeads(Carbon $since, ?Carbon $to = null, ?string $crmProfileId = null): int;\n\n // Sync single records.\n public function syncContact(string $crmId): ?Contact;\n\n public function syncOpportunity(string $crmId): ?Opportunity;\n\n public function syncAccount(string $crmId): ?Account;\n\n public function syncLead(string $crmId): ?Lead;\n\n public function importStages(?array $types = null, ?string $missingStageName = null): ?Stage;\n\n public function syncOrganization(): void;\n\n /**\n * Text search for CRM Objects.\n *\n * @param string $name\n * @param array $scopes\n *\n * @return array\n */\n public function find(string $name, array $scopes): array;\n\n /**\n * Get the Opportunities for an Account.\n *\n * @param null|string $crmAccountId\n * @param null|string $crmContactId\n *\n * @return array\n */\n public function findOpportunities(?string $crmAccountId, ?string $crmContactId, ?int $userId = null): array;\n\n /**\n * Get the Tasks for an object.\n *\n * @param string $objectType\n * @param string $objectId\n * @param string|null $opportunityId\n *\n * @return array\n */\n public function getTasks(string $objectType, string $objectId, ?string $opportunityId): array;\n\n /**\n * Try to find email address in CRM service\n *\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchExactlyByEmail(string $email, ?int $userId = null): ?array;\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n *}\n */\n public function matchByPhone(string $phone, ?string $rawPhoneNumber = null, ?int $userId = null): ?array;\n\n /**\n * @return null|array{\n * Lead|null,\n * Account|null,\n * Opportunity|null,\n * Contact|null,\n * Stage|null,\n * string|null\n * }\n */\n public function matchByName(string $name, ?int $userId = null): ?array;\n\n /**\n * @param Activity $activity\n *\n * @return Activity\n */\n public function saveActivity(Activity $activity): Activity;\n\n /**\n * @param Activity $activity\n * @param array $fields\n *\n * @return null|string\n */\n public function saveFollowupActivity(Activity $activity, array $fields): ?string;\n\n /**\n * @param $crmObject\n * @param Stage $stage\n */\n public function updateStage($crmObject, Stage $stage): void;\n\n /**\n * @param User|null $userToSearch\n *\n * @return Profile|null\n */\n public function syncProfiles(?User $userToSearch = null): ?Profile;\n\n /**\n * @param string $providerId\n * @param string $objectType\n *\n * @return null|string\n */\n public function generateProviderUrl(string $providerId, string $objectType): ?string;\n\n /**\n * @param string $objectType\n * @param string $objectId\n * @param array $data\n * @param array $headers\n */\n public function updateRecord(string $objectType, string $objectId, array $data, array $headers = []): void;\n\n /**\n * @param string $objectType\n * @param string $objectId\n * @param array $fields\n *\n * @return array\n */\n public function getRecord(string $objectType, string $objectId, array $fields = []): array;\n\n public function getConfiguration(): Configuration;\n\n public function setConfiguration(Configuration $config): void;\n\n /** @return array<int, array<string, string>> */\n public function getDealInsightsFields(): array;\n\n /** A most useless method */\n public function getMinimumApiVersion(): int|float|string;\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},{"role":"AXStaticText","text":"app ~/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".circleci","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".cursor","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".github","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".sonarlint","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".vscode, folder","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":".windsurf","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"app, sources root","depth":7,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Actions","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Component","depth":8,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Acl","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActionItems, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Activity, folder","depth":9,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"ActivityAnalytics","depth":9,"on_screen":false,"role_description":"text"}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3646
|
134
|
17
|
2026-05-07T12:32:44.378793+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157164378_m2.jpg...
|
PhpStorm
|
faVsco.js – Pipedrive/Service.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
master, menu
|
[{"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}]...
|
-7673782238848625796
|
-8646559087753982588
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
master, menu
PhostormINav Project: faVsco.js, menu
master, menu
PhostormINavigareCodeLaravelFV faVsco.jsC DummyC HelpersC) AddRateLimitCommand.pnp• _ huosootTImportBatchJobTrait.phgAccountsyncStrateayw ActionsD ContactSyncStrategy•DDTOC FieldsHournallM Metadatau Hubspot//syncermenuuestrait.onov OpportunitvSvncStrate>MConcernsC) HubsootLastModifie© HubspotLastModifieC) Hubsnotl astModitit©HubspotLastModifie(C) Hubsnotl astModifi.© HubspotSingleSync© HubspotSyncStrate© HubspotWebhookB› Pagination> D ProspectSearchStratecC Redisv 0 ServiceTraitsu Uooonunitysyncifu syncermentitiesira© SyncFieldsTrait.php© WriteCrmTrait.php> C Utils> 0 Webhookc8atchsvnccollector.onC) BatchSvncRedisServic@ Client.ohrC) Closed Dea [EMAIL]) DecorateActivitv.ono@ FieldDefinitions.ohnC SieldiivneConverter.oh© HubspotClientinterface© HubspotTokenManage© PayloadBuilder.php(C) RemoteCrmObiectMang ResponseNormalize.ph(C Corvice nhni© SyncFieldAction.php(C) SuncPolntodActivitvMe© WebhookSyncBatchPrv C IntegrationApp> ( Accessors> C Api.> C Confia2022namesoace Jaminny Services crm. Pipedrive:use Carbon. Carbonsuse Devio Pioedrive Excentions TtemNotFoundExcention:use Devio Pipedrive \Exceptions PipedriveException;use Excentionsuse Illuminate\Support \Facades \Cache;use InvalidArgumentException;use Jiminny\Contracts\Services\Crm\ClientInterface;use Jiminny\Contracts\Services\Crm\LayoutManagementInterface:use Jiminny\Contracts\Services\Crm\MatchCrmEntitiesInterface;use Jiminny\Contracts\Services\Crm \Provider\PipedriveInterface:use Jiminhy contracts services cru kenotechelcyLookupintertace.use Jiminny \Contracts\Services\Crm\RemoteEntityManipulationInterfaceuse vininny contracts services urn sertinostnterraceuse Jiminny Contracts\Services\Crm\SyncCrmEntitiesInterfaceuse Jiminny Lontracts services crm syncurmmetadatalntertaceuse Jiminny Lontracts services Crm Veritylaskzx1stsintertace:use Jiminny Events Users Soc1aLAccountu1sconnectedsuse Jiminny Exceptions CrmException:use Jiminny Exceptions Httpnotroundexcept1onuse Jiminny\Exceptions\SocialAccountTokenInvalidExceptionuse Jaminny voos Crm.matchactivitlesonewipportunitvuse Jiminny Models\Accountuse Jiminny Models Activityuse Jiminny Models Contactuse Jiminny Models Crm BusinessProcess:use Jiminny Models Crm Confiaurationsuse Jiminny Models Crm Field:use Jiminny Models\Crm\FieldData;use Jiminnv Models Crm Profile:use Jiminnv Models.Crm RecordTvne.use Jiminnv Models Lead:use Jiminny Models \Opportunity:use Jiminny Models\Playbook;use Jiminny \Models\SocialAccount;use Jiminny Models Stage:use Jiminny Models User:use Jiminny Repositories Crm\FieldRepository:use Jiminny Repositories Crm ProfileRepository:use Jiminny Services Avatar\ProspectPhotoPathService:use Jiminny Services\Crm BaseServiceuse Jiminny services crm Upportunitysyncstrateqykesolverause Jaminny Urls LurrencvrormatterQube for INF suadections: Netect more cecurity iccuec in vour DHP filec II Try SonarQube Cloud for free /I DownloadQuhe Sorver Il Iearn more /I Don't ack adain (todav 10-25)RateLimitException.php© SyncToUserPilot.phpkateLimitawarewrapper.pngT IntegrationApp/.../SyncCrmEntitiesTrait.phpare/RateLimited.pnp© Http/RateLimited.php)BaserateLimiter.phpHubspot/service.ongLukas/Stefka 121 - in 1h 58mThu 7 May 15:32:44AskJiminnyReportActivityServiceTest= custom.log« SF [jiminny@localhost]A HS_local [(jiminny@localhost]« console [PROD]& console [STAGINGIQ- Hubspot22R Match case[2026-05-07 12:28:14] local.INF0: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities" "memoryBeforeCommandInMb":62.0, "memo "[2026-05-07 12:28:17] local.INF0:[SocialAccountService] Fetching token {"socialAccountId":1499, "provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344"|[2026-05-07 12:28:17] local.INF0:ISOCHALACCOUnLSENVACeILOKENNeEusNeTesinoEtSOctaLACCOUncLoN147FONOVLden nUDSDосизвсом мешатоюномн45555174-0545-40488осУа-C4OCOВ[2026-05-07 12:28:17] local.INF0:[EncryptedTokenManager] Generating access token. {"mode": "legacy"} {"correlation_id": "273355f2-6315-4b20-bc9a-c26c681d6344", "trace_id" : "5ea79[2026-05-07 12:28:171 Local.INF0: [SocialAccountServicel Refreshing token from provider {"socialAccountId":1499, "providen" : "hubspot", "refreshToken" : "96f94c623a404e02ebdbf07f1b[2026-05-07 12:28:18] local.NOTICE: Monitoring start{"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5", "trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5" "trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"]2026-05-07 12:28:18 Local.INF0:[SocialAccountObserverl Saving model {"correlation id"."273355f2-6315-4b20-bc9a-c26c681d6344" "trace id". "Sea79a26-c838-48e8-9913-93ad5081462026-05-07 12:28:18 Local.INF0:SocialAccountloserver Access token was modhrled, encrvotino"correlation 1d": [CREDIT_CARD]-0c9a-026068106544""trace 1d":"Sea/2a26.[2026-05-07 12:28:181 local, INF0:[SocialAccountService] Token refreshed {"socialAccountId":1499, "provider": "hubspot", "state": "connected"} {"correlation_id":"273355f2-6315-4b22026-05-07 12:28:18 Local.INF0:comownerReso ver Dntednattion owner matched as CRM ownenwcem orovader hubspotucom ownen r28.team a Wconnellatiion ШR 206k15512(2026-05-07 12:28:191 local, INF0:[Hubspot] Failed to fetch opportunity {"crm_id":"374720564", "reason":"[429] Client error: 'GET https://api.hubapi.com/crm/v3/objects/deals/37i\"status\": "error)", "message\":\"You have reached your ten_secondly_rolling limit.", "errorType\":\"RATE_LIMIT\", "correlationid)" (truncated...)"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344"', "trace_id": "5ea79a26-c838-48e8-9913-93ad508146a6"}2026-05-01 12-28-10 1 ocalERROR: 420 Mtient erron.GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Cc{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationid" (truncated...){"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error:'GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_obj{\"status\":\"error\", \"message\":\"You have reached your ten_secondly_rolling limit.","errorType\":"RATE_LIMIT)","correlationId)" (truncated...)at/home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)stacktnace#0/home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot||Client||CrmDeals\Api BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm|\Deals|\Api\\BasicApi->getById(^374720564', 'hs_object_id,de..'.'companies,conta...')#2/home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/0pportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)#3/home/jiminny/app/Console/Commands/JiminnyDebuqCommand.php(351): Jiminny||Services|\Crm|\Hubspotl|Service->syncOpportunitv(^374720564')#4/home/jiminny/app/Console/Commands/JiminnyDebuqCommand.php(44): Jiminny\Consolel\Commands|JiminnyDebuqCommand->rateLimit#5 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny|\Consolel|Commands||JiminnyDebugCommand->handle(Obiect(Jiminny||Jobs||JobDispat#6/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::Illuminate\Container{closurelO#7/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminatel|Container| \Util::unwrapIfClosure(0biect(Closure))#8/home/jiminny/vendon/Lanavel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminatel|Container|BoundMethod::callBoundMethod(Obriect(Illuminatel|FoundationllAppl#9/home/iiminny/vendoc/anavel//fnamewock/scc/T11uminate/Container/Containen.oho(799):_T1luminatel\Containec||BoundMethod..cal1(Obiect(T1luminatel\Eoundation/Aoolication)._Annand//Command.oho (3410: TLuminateConsoleCommand-›execute(Obiect SumfonyComponent ConsoleInout Aravinout). Obiect onlumina#13 /home/iiminny/vendor/symfony//console/Aoolication.oho(1117):_Tlluminatel|ConsolelICommand->cunCObiect(Svmfonv/Comoonent/Consolel\Innutl\AnqvInout)._Object(SymfonvIlCompon#15/home/jiminny/vendor/svmfonv/console/AopLication.phv(195): Svmfonv||Component||Consolel\Aoplication->doRun(0biect(Svmfonv||Component|\Consolel\Inputl\AravInout). Obiect(Sv#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony|\Component|\Console\#17/home/Liiminny/vendor/lanavelLfoamewock/sec/Tluminate/Eoundation/Annlication..nhn(1235)._Illuminatel\Eoundationl\Consolel\Kernel->handle(0hsiect(SvmfonvlComnonentl/Ronsolel#18 /home/&iminnv/antisan(13): Tlluminatel|Foundation| \AnnLication->handleCommand(0biect(Svmfonv|\Comnonent||Console||Tnnut|\AravTnnut))m9 tnainelation a": 127335542-6315-4620-b90-0266681634, "tпace-2а": "5887926- [PHONE]-93d5081466-712926-05-07 12-282201ncaLNENR Nm nny MonsdlAMmnandadommandacin Memoay lsane hefoce stastiing command command"-"maitlhoxaskin-listcanefinesh""memonvRefoceRommandiTnMh"r[2026-05-07 12:28:20] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command" : "mailbox:skip-lists:refresh", "memoryBeforeCommandInMb" : 62.0, "memory[2026-05-07 12:28:24 local.INF0: Jiminny Console \Commands Command::run Memory usage before starting command {"command" : "mailbox:batch:process", "memoryBeforeCommandInMb" :62.012a24-05-07 12.29.241 1oc01 TNEO.[EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8"' "trace_id":"67798138r2a24-05-07 12.29.041 1oc01 TNE0•imal Schedmlall STNTSHEn hatch neacnse fllhastl -"docken lamn 14 tnnaceecadl-0llconcollationAdH.1d101d5ch-1226-/A301-R0d/-d285d0d7,8h8" Itnace[2026-05-07 12:28:24] local.INF0: Jiminny|Console\Commands\Command::run Memory usage for command {"command": "mailbox:batch:process", "memonyBeforeCommandInMb":62.0, "memoryAfter[2026-05-07 12:28:27] local.INF0: Jiminny|Console\Commands\Command::run Memory usage before starting command {"command":"conference: moniton:count", "memoryBeforeCommandInMb" : 62[2026-05-07 12:28:27] local.INF0: Running conference:moniton:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"conrelation id":"a4e5e18f-9f8c-4196-raanz hсA7 42.09.091 1aл01 TАCA.[conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation id":"a4e5e18f-9f8c-4196-ace0-bf66W Windsurf Teamsio 4 spaces...
|
3644
|
NULL
|
NULL
|
NULL
|
|
3645
|
133
|
10
|
2026-05-07T12:32:46.069517+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157166069_m1.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Search
ServiceInterface \Jiminny\Contracts\Servi Search
ServiceInterface \Jiminny\Contracts\Services\Crm, public abstract method
MatchCrmEntitiesInterface \Jiminny\Contracts\Services\Crm, public abstract method
Choose parent method to navigate
Open in Find Tool Window...
|
[{"role":"AXTextField","text [{"role":"AXTextField","text":"Search","depth":1,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"ServiceInterface \\Jiminny\\Contracts\\Services\\Crm, public abstract method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"MatchCrmEntitiesInterface \\Jiminny\\Contracts\\Services\\Crm, public abstract method","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Choose parent method to navigate","depth":1,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"","depth":1,"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Open in Find Tool Window","depth":1,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-6984315234562922920
|
2752128150021829771
|
click
|
accessibility
|
NULL
|
Search
ServiceInterface \Jiminny\Contracts\Servi Search
ServiceInterface \Jiminny\Contracts\Services\Crm, public abstract method
MatchCrmEntitiesInterface \Jiminny\Contracts\Services\Crm, public abstract method
Choose parent method to navigate
Open in Find Tool Window...
|
3642
|
NULL
|
NULL
|
NULL
|
|
3644
|
134
|
16
|
2026-05-07T12:32:35.260316+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157155260_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Find in Files
100+ matches in 37+ files
File mask: Find in Files
100+ matches in 37+ files
File mask:
*.php
*.php
Auto
*.php
Filter Search Results
Pin Window
Search History
matchBy
New Line
Match case
Words
Regex
Replace History
Replace
New Line
Preserve case
In Project
Module
Directory
Scope
Module
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/ServiceTraits
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/ServiceTraits
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot
/Users/lukas/jiminny/app/app/Exceptions
/Users/lukas/jiminny/app/app/Listeners/Crm
/Users/lukas/jiminny/app/app/Component/Queue/Job
/Users/lukas/jiminny/app/app/Listeners/AutomatedReports/UserPilot
/Users/lukas/jiminny/app/app/Events/Crm
/Users/lukas/jiminny/app/app/Jobs/AutomatedReports
/Users/lukas/jiminny/app/app/Listeners/Activities/Coaching/UserPilot
/Users/lukas/jiminny/app/app/Listeners/Activities/ActivityProvider/UserPilot
/Users/lukas/jiminny/app/app/Jobs/Activity/PushSummaryToCrm
/Users/lukas/jiminny/app/app/Repositories/Crm
/Users/lukas/jiminny/app/app/Jobs/Crm/Delete
/Users/lukas/jiminny/app/app/Services/Kiosk/AutomatedReports
/Users/lukas/jiminny/app/app/Http/Controllers/API/UserAutomatedReports
/Users/lukas/jiminny/app/app/Services/Crm/Salesforce
/Users/lukas/jiminny/app/app/Providers
/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp
/Users/lukas/jiminny/app/app/Events/Activities/Crm
/Users/lukas/jiminny/app/app/Listeners/Playbooks
/Users/lukas/jiminny/app/app/Console/Commands/Crm
/Users/lukas/jiminny/app/app/Services/Crm
/Users/lukas/jiminny/app/app/Http/Controllers
/Users/lukas/jiminny/app/app/Console/Commands/Reports
/Users/lukas/jiminny/app/app/VO/Repository/OnDemandActivitySearch
/Users/lukas/jiminny/app/app/Listeners/Activities/Conferences/UserPilot
/Users/lukas/jiminny/app/app/Http/Controllers/Webhook
/Users/lukas/jiminny/app/resources/views/emails/reports
/Users/lukas/jiminny/app/app/Mail/Reports
/Users/lukas/jiminny/app/app/Repositories
/Users/lukas/jiminny/app/app/Component/ActivitySearch/Service
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Salesforce
/Users/lukas/jiminny/app/routes
/Users/lukas/jiminny/app/app/Console/Commands
/Users/lukas/jiminny/app/database/migrations
/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/325d461a-c90f-430a-99d4-6ddfce0c61d7
/Users/lukas/jiminny/app/app/Http/Controllers/API/V2
/Users/lukas/jiminny/app/app/Jobs/Crm/Hubspot
/Users/lukas/jiminny/app/app/Component/DealInsights
/Users/lukas/jiminny/app/app/Policies
/Users/lukas/jiminny/app/app/Services/Crm/Helpers
/Users/lukas/jiminny/app/app/Jobs/Crm
/Users/lukas/jiminny/app/app/Models
/Users/lukas/jiminny/app/app/Listeners/Teams
/Users/lukas/jiminny/app/app/Jobs/Crm/Salesforce
/Users/lukas/jiminny/app/app
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Journal
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/OpportunitySyncStrategy
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Webhook
/Users/lukas/jiminny/app/storage/logs
/Users/lukas/jiminny/app
/Users/lukas/jiminny/app/app/Services/Internal
/Users/lukas/jiminny/app/app/Listeners/Transcription
/Users/lukas/jiminny/app/tests/Unit/Listeners/Teams
/Users/lukas/jiminny/app/app/Models/Crm
/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/91133dfa-8d71-4e12-bfb8-fec7f1afba8f
/Users/lukas/jiminny/app/app/Observers
/Users/lukas/jiminny/app/app/Services/Mail
/Users/lukas/jiminny/app/app/Console/Commands/Activities
/Users/lukas/jiminny/app/app/Console/Commands/Activities/Migrator
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/ServiceTraits
/Users/lukas/jiminny/app/app/Jobs/User
/Users/lukas/jiminny/app/app/Models/Activity
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/Webhook
/Users/lukas/jiminny/app/app/Component/AiAutomation/Listeners/PendingAnalysis
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot
/Users/lukas/jiminny/app/app/Component/ActivitySearch/FilterDefinition/DealInsights
/Users/lukas/jiminny/app/app/Services/Crm/DecorateActivity
/Users/lukas/jiminny/app/app/Component/Activity/Event
/Users/lukas/jiminny/app/app/Component/Sidekick
/Users/lukas/jiminny/app/app/Listeners/Activities/Conferences
/Users/lukas/jiminny/app/app/Listeners/Activities/Bots
/Users/lukas/jiminny/app/app/Services/RecallAI/Webhooks/Handlers
/Users/lukas/jiminny/app/app/Events/Activities/Bots
/Users/lukas/jiminny/app/app/Component/MeetingBot
/Users/lukas/jiminny/app/app/Services/Activity/RingCentral
/Users/lukas/jiminny/app/app/Http/Controllers/Webhook/Hubspot
/Users/lukas/jiminny/app/app/Services/Activity/Gmail
/Users/lukas/jiminny/app/app/Services/Crm/CrmObjects/ServiceTraits
/Users/lukas/jiminny/app/app/Jobs/Mailbox
/Users/lukas/jiminny/app/app/Console
/Users/lukas/jiminny/app/front-end/src/composables
/Users/lukas/jiminny/app/app/Console/Commands/Calendars
/Users/lukas/jiminny/app/app/Http/Controllers/API
/Users/lukas/jiminny/app/app/Http/Controllers/Internal/WebhookReceiver
/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp/ServiceTraits
/Users/lukas/jiminny/app/app/Component/Queue
/Users/lukas/jiminny/app/app/Console/Commands/Crm/Hubspot
/Users/lukas/jiminny/app/app/Component/Transcription/Job
/Users/lukas/jiminny/app/tests/Unit/Services/Listeners
/Users/lukas/jiminny/app/app/Services/Crm/Listeners
/Users/lukas/jiminny/app/app/Traits
/Users/lukas/jiminny/app/tests/Unit/Jobs/Crm/Hubspot
/Users/lukas/jiminny/app/tests/Unit/Services/Crm
/Users/lukas/jiminny/app/app/Services/Activity
/Users/lukas/jiminny/app/app/Services/Calendar/Command
/Users/lukas/jiminny/app/.idea/queries
/Users/lukas/jiminny/app/vendor/hubspot/api-client/codegen/Crm
/Users/lukas/jiminny/app/vendor/hubspot
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Fields
/Users/lukas/jiminny/app/app/Services/Crm/Copper
/Users/lukas/jiminny/app/app/Services/Crm/Bullhorn
/Users/lukas/jiminny/app/app/Notifications/Channels
/Users/lukas/jiminny/app/tests/Unit
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/Journal
/Users/lukas/jiminny/app/app/Interactions/Settings/Teams
/Users/lukas/jiminny/app/app/Exceptions/Crm
/Users/lukas/jiminny/app/vendor/hubspot/hubspot-php/src/Endpoints
/Users/lukas/jiminny/app/config
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/OpportunitySyncStrategy
/Users/lukas/jiminny/app/vendor/laravel/framework/src/Illuminate/Redis/Connections
/Users/lukas/jiminny/app/app/Http/Controllers/Settings/Teams
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Webhook/Traits
/Users/lukas/jiminny/app/vendor/laravel/framework/src/Illuminate/Broadcasting
/Users/lukas/jiminny/app/app/Component/FeatureFlags
/Users/lukas/jiminny/app/app/Component/Activity
/Users/lukas/jiminny/app/app/Component/ActivitySearch
/Users/lukas/jiminny/app/tests/Unit/Events/Activities/Crm
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/Pagination
/Users/lukas/jiminny/app/app/Console/Commands/Dev
/Users/lukas/jiminny/app/front-end
/Users/lukas/jiminny/app/app/Component/Prophet
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/IntegrationApp
/Users/lukas/jiminny/app/app/Component/AskAnything
/Users/lukas/jiminny/app/app/Component/AskJiminnyAi/OnDemandLevel/Events
/Users/lukas/jiminny/app/app/Component/AskAnything/Events
/Users/lukas/jiminny/app/app/Component/AskJiminnyAi/DealLevel/Traits
/Users/lukas/jiminny/app/app/Component/ProphetAi
/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/d1e2c340-64e9-49c6-aa9a-196201874532
/Users/lukas/jiminny/app/app/Http/Controllers/API/Page
/Users/lukas/jiminny/app/front-end/src/components/ondemand/ActivityList
/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/5b1549d5-9876-4d9e-9ce3-025f12a83283
/Users/lukas/jiminny/app/app/Contracts/Repositories
/Users/lukas/jiminny/app/app/Http/Controllers/Kiosk
/Users/lukas/jiminny/app/app/Component/AiAutomation/Actions
/Users/lukas/jiminny/app/app/Services/Activity/HubSpot
/Users/lukas/jiminny/app/app/Services/Crm/Pipedrive
/Users/lukas/jiminny/app/app/Jobs/Activity/Import
/Users/lukas/jiminny/app/app/Events/Import
/Users/lukas/jiminny/app/app/Events/Activities/Dialers
/Users/lukas/jiminny/app/tests
/Users/lukas/jiminny/app/app/Events/Activities
/Users/lukas/jiminny/app/tests/Unit/Jobs/Activity/PushSummaryToCrm
/Users/lukas/jiminny/app/app/Console/Commands/Analytics
/Users/lukas/jiminny/app/tests/Unit/Services/Kiosk/AutomatedReports
/Users/lukas/jiminny/app/app/Http/Middleware
/Users/lukas/jiminny/app/app/Http/Controllers/Auth
/Users/lukas/jiminny/app/tests/Unit/Jobs/Crm
/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp/Api
/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp/Accessors
/Users/lukas/jiminny/app/app/Services/Crm/Close
/Users/lukas/jiminny/app/app/Services
/Users/lukas/jiminny/app/app/Http/Transformers
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Pipedrive
/Users/lukas/jiminny/app/app/Listeners/Activities/Crm/Summary
/Users/lukas/jiminny/app/app/Services/Activity/AmazonConnect
/Users/lukas/jiminny/app/app/Models/Participant
/Users/lukas/jiminny/app/app/Events/Activities/Connections
/Users/lukas/jiminny/app/app/Listeners/Activities/Crm...
|
[{"role":"AXStaticText","text& [{"role":"AXStaticText","text":"Find in Files","depth":1,"bounds":{"left":0.2992021,"top":0.12609737,"width":0.024601065,"height":0.013567438},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"100+ matches in 37+ files","depth":1,"bounds":{"left":0.32779256,"top":0.12609737,"width":0.052526597,"height":0.013567438},"on_screen":true,"role_description":"text"},{"role":"AXCheckBox","text":"File mask:","depth":1,"bounds":{"left":0.5315825,"top":0.12290503,"width":0.029587766,"height":0.019952115},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"*.php","depth":1,"bounds":{"left":0.5621675,"top":0.11971269,"width":0.027925532,"height":0.027134877},"on_screen":true,"value":"*.php","role_description":"combo box","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"*.php","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"Auto","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXTextField","text":"*.php","depth":2,"bounds":{"left":0.5661569,"top":0.12609737,"width":0.011635638,"height":0.013567438},"on_screen":true,"value":"*.php","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Filter Search Results","depth":1,"bounds":{"left":0.5944149,"top":0.12290503,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Pin Window","depth":1,"bounds":{"left":0.6037234,"top":0.12290503,"width":0.00731383,"height":0.017557861},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Search History","depth":1,"bounds":{"left":0.2962101,"top":0.15403032,"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":"matchBy","depth":2,"bounds":{"left":0.30718085,"top":0.15403032,"width":0.26196808,"height":0.017557861},"on_screen":true,"value":"matchBy","role_description":"text entry area","is_enabled":true,"is_focused":true,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"New Line","depth":1,"bounds":{"left":0.578125,"top":0.15403032,"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":1,"bounds":{"left":0.5880984,"top":0.15403032,"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":1,"bounds":{"left":0.59674203,"top":0.15403032,"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":1,"bounds":{"left":0.60538566,"top":0.15403032,"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":1,"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":2,"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":1,"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":1,"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":"AXButton","text":"In Project","depth":2,"bounds":{"left":0.2992021,"top":0.1867518,"width":0.022938829,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Module","depth":2,"bounds":{"left":0.32214096,"top":0.1867518,"width":0.019281914,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Directory","depth":2,"bounds":{"left":0.3414229,"top":0.1867518,"width":0.022606382,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Scope","depth":2,"bounds":{"left":0.36402926,"top":0.1867518,"width":0.017287234,"height":0.018355945},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXPopUpButton","text":"Module","depth":1,"bounds":{"left":0.27027926,"top":1.0,"width":0.099734046,"height":0.0},"on_screen":false,"role_description":"pop up button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXComboBox","text":"/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/ServiceTraits","depth":1,"bounds":{"left":0.27027926,"top":1.0,"width":0.1974734,"height":0.0},"on_screen":false,"value":"/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/ServiceTraits","role_description":"combo box","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/ServiceTraits","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Hubspot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Exceptions","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/Queue/Job","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/AutomatedReports/UserPilot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Events/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/AutomatedReports","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Activities/Coaching/UserPilot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Activities/ActivityProvider/UserPilot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/Activity/PushSummaryToCrm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Repositories/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/Crm/Delete","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Kiosk/AutomatedReports","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/API/UserAutomatedReports","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Salesforce","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Providers","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Events/Activities/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Playbooks","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console/Commands/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console/Commands/Reports","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/VO/Repository/OnDemandActivitySearch","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Activities/Conferences/UserPilot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/Webhook","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/resources/views/emails/reports","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Mail/Reports","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Repositories","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/ActivitySearch/Service","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Salesforce","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/routes","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console/Commands","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/database/migrations","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/325d461a-c90f-430a-99d4-6ddfce0c61d7","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/API/V2","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/Crm/Hubspot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/DealInsights","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Policies","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Helpers","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Models","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Teams","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/Crm/Salesforce","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Journal","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/OpportunitySyncStrategy","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Webhook","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/storage/logs","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Internal","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Transcription","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Listeners/Teams","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Models/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/91133dfa-8d71-4e12-bfb8-fec7f1afba8f","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Observers","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Mail","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console/Commands/Activities","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console/Commands/Activities/Migrator","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/ServiceTraits","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/User","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Models/Activity","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/Webhook","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/AiAutomation/Listeners/PendingAnalysis","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/ActivitySearch/FilterDefinition/DealInsights","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/DecorateActivity","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/Activity/Event","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/Sidekick","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Activities/Conferences","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Activities/Bots","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/RecallAI/Webhooks/Handlers","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Events/Activities/Bots","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/MeetingBot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Activity/RingCentral","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/Webhook/Hubspot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Activity/Gmail","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/CrmObjects/ServiceTraits","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/Mailbox","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/front-end/src/composables","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console/Commands/Calendars","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/API","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/Internal/WebhookReceiver","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp/ServiceTraits","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/Queue","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console/Commands/Crm/Hubspot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/Transcription/Job","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Listeners","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Listeners","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Traits","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Jobs/Crm/Hubspot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Activity","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Calendar/Command","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/.idea/queries","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/vendor/hubspot/api-client/codegen/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/vendor/hubspot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Fields","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Copper","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Bullhorn","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Notifications/Channels","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/Journal","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Interactions/Settings/Teams","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Exceptions/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/vendor/hubspot/hubspot-php/src/Endpoints","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/config","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/OpportunitySyncStrategy","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/vendor/laravel/framework/src/Illuminate/Redis/Connections","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/Settings/Teams","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Webhook/Traits","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/vendor/laravel/framework/src/Illuminate/Broadcasting","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/FeatureFlags","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/Activity","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/ActivitySearch","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Events/Activities/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/Pagination","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console/Commands/Dev","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/front-end","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/Prophet","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm/IntegrationApp","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/AskAnything","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/AskJiminnyAi/OnDemandLevel/Events","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/AskAnything/Events","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/AskJiminnyAi/DealLevel/Traits","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/ProphetAi","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/d1e2c340-64e9-49c6-aa9a-196201874532","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/API/Page","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/front-end/src/components/ondemand/ActivityList","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/5b1549d5-9876-4d9e-9ce3-025f12a83283","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Contracts/Repositories","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/Kiosk","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Component/AiAutomation/Actions","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Activity/HubSpot","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Pipedrive","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Jobs/Activity/Import","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Events/Import","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Events/Activities/Dialers","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Events/Activities","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Jobs/Activity/PushSummaryToCrm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Console/Commands/Analytics","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Kiosk/AutomatedReports","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Middleware","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Controllers/Auth","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Jobs/Crm","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp/Api","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp/Accessors","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Crm/Close","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Http/Transformers","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Pipedrive","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Activities/Crm/Summary","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Services/Activity/AmazonConnect","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Models/Participant","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Events/Activities/Connections","depth":6,"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"/Users/lukas/jiminny/app/app/Listeners/Activities/Crm","depth":6,"on_screen":false,"role_description":"text"}]...
|
1393553565681986000
|
-5202989754022267263
|
visual_change
|
accessibility
|
NULL
|
Find in Files
100+ matches in 37+ files
File mask: Find in Files
100+ matches in 37+ files
File mask:
*.php
*.php
Auto
*.php
Filter Search Results
Pin Window
Search History
matchBy
New Line
Match case
Words
Regex
Replace History
Replace
New Line
Preserve case
In Project
Module
Directory
Scope
Module
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/ServiceTraits
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/ServiceTraits
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot
/Users/lukas/jiminny/app/app/Exceptions
/Users/lukas/jiminny/app/app/Listeners/Crm
/Users/lukas/jiminny/app/app/Component/Queue/Job
/Users/lukas/jiminny/app/app/Listeners/AutomatedReports/UserPilot
/Users/lukas/jiminny/app/app/Events/Crm
/Users/lukas/jiminny/app/app/Jobs/AutomatedReports
/Users/lukas/jiminny/app/app/Listeners/Activities/Coaching/UserPilot
/Users/lukas/jiminny/app/app/Listeners/Activities/ActivityProvider/UserPilot
/Users/lukas/jiminny/app/app/Jobs/Activity/PushSummaryToCrm
/Users/lukas/jiminny/app/app/Repositories/Crm
/Users/lukas/jiminny/app/app/Jobs/Crm/Delete
/Users/lukas/jiminny/app/app/Services/Kiosk/AutomatedReports
/Users/lukas/jiminny/app/app/Http/Controllers/API/UserAutomatedReports
/Users/lukas/jiminny/app/app/Services/Crm/Salesforce
/Users/lukas/jiminny/app/app/Providers
/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp
/Users/lukas/jiminny/app/app/Events/Activities/Crm
/Users/lukas/jiminny/app/app/Listeners/Playbooks
/Users/lukas/jiminny/app/app/Console/Commands/Crm
/Users/lukas/jiminny/app/app/Services/Crm
/Users/lukas/jiminny/app/app/Http/Controllers
/Users/lukas/jiminny/app/app/Console/Commands/Reports
/Users/lukas/jiminny/app/app/VO/Repository/OnDemandActivitySearch
/Users/lukas/jiminny/app/app/Listeners/Activities/Conferences/UserPilot
/Users/lukas/jiminny/app/app/Http/Controllers/Webhook
/Users/lukas/jiminny/app/resources/views/emails/reports
/Users/lukas/jiminny/app/app/Mail/Reports
/Users/lukas/jiminny/app/app/Repositories
/Users/lukas/jiminny/app/app/Component/ActivitySearch/Service
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Salesforce
/Users/lukas/jiminny/app/routes
/Users/lukas/jiminny/app/app/Console/Commands
/Users/lukas/jiminny/app/database/migrations
/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/325d461a-c90f-430a-99d4-6ddfce0c61d7
/Users/lukas/jiminny/app/app/Http/Controllers/API/V2
/Users/lukas/jiminny/app/app/Jobs/Crm/Hubspot
/Users/lukas/jiminny/app/app/Component/DealInsights
/Users/lukas/jiminny/app/app/Policies
/Users/lukas/jiminny/app/app/Services/Crm/Helpers
/Users/lukas/jiminny/app/app/Jobs/Crm
/Users/lukas/jiminny/app/app/Models
/Users/lukas/jiminny/app/app/Listeners/Teams
/Users/lukas/jiminny/app/app/Jobs/Crm/Salesforce
/Users/lukas/jiminny/app/app
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Journal
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/OpportunitySyncStrategy
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Webhook
/Users/lukas/jiminny/app/storage/logs
/Users/lukas/jiminny/app
/Users/lukas/jiminny/app/app/Services/Internal
/Users/lukas/jiminny/app/app/Listeners/Transcription
/Users/lukas/jiminny/app/tests/Unit/Listeners/Teams
/Users/lukas/jiminny/app/app/Models/Crm
/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/91133dfa-8d71-4e12-bfb8-fec7f1afba8f
/Users/lukas/jiminny/app/app/Observers
/Users/lukas/jiminny/app/app/Services/Mail
/Users/lukas/jiminny/app/app/Console/Commands/Activities
/Users/lukas/jiminny/app/app/Console/Commands/Activities/Migrator
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/ServiceTraits
/Users/lukas/jiminny/app/app/Jobs/User
/Users/lukas/jiminny/app/app/Models/Activity
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/Webhook
/Users/lukas/jiminny/app/app/Component/AiAutomation/Listeners/PendingAnalysis
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot
/Users/lukas/jiminny/app/app/Component/ActivitySearch/FilterDefinition/DealInsights
/Users/lukas/jiminny/app/app/Services/Crm/DecorateActivity
/Users/lukas/jiminny/app/app/Component/Activity/Event
/Users/lukas/jiminny/app/app/Component/Sidekick
/Users/lukas/jiminny/app/app/Listeners/Activities/Conferences
/Users/lukas/jiminny/app/app/Listeners/Activities/Bots
/Users/lukas/jiminny/app/app/Services/RecallAI/Webhooks/Handlers
/Users/lukas/jiminny/app/app/Events/Activities/Bots
/Users/lukas/jiminny/app/app/Component/MeetingBot
/Users/lukas/jiminny/app/app/Services/Activity/RingCentral
/Users/lukas/jiminny/app/app/Http/Controllers/Webhook/Hubspot
/Users/lukas/jiminny/app/app/Services/Activity/Gmail
/Users/lukas/jiminny/app/app/Services/Crm/CrmObjects/ServiceTraits
/Users/lukas/jiminny/app/app/Jobs/Mailbox
/Users/lukas/jiminny/app/app/Console
/Users/lukas/jiminny/app/front-end/src/composables
/Users/lukas/jiminny/app/app/Console/Commands/Calendars
/Users/lukas/jiminny/app/app/Http/Controllers/API
/Users/lukas/jiminny/app/app/Http/Controllers/Internal/WebhookReceiver
/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp/ServiceTraits
/Users/lukas/jiminny/app/app/Component/Queue
/Users/lukas/jiminny/app/app/Console/Commands/Crm/Hubspot
/Users/lukas/jiminny/app/app/Component/Transcription/Job
/Users/lukas/jiminny/app/tests/Unit/Services/Listeners
/Users/lukas/jiminny/app/app/Services/Crm/Listeners
/Users/lukas/jiminny/app/app/Traits
/Users/lukas/jiminny/app/tests/Unit/Jobs/Crm/Hubspot
/Users/lukas/jiminny/app/tests/Unit/Services/Crm
/Users/lukas/jiminny/app/app/Services/Activity
/Users/lukas/jiminny/app/app/Services/Calendar/Command
/Users/lukas/jiminny/app/.idea/queries
/Users/lukas/jiminny/app/vendor/hubspot/api-client/codegen/Crm
/Users/lukas/jiminny/app/vendor/hubspot
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Fields
/Users/lukas/jiminny/app/app/Services/Crm/Copper
/Users/lukas/jiminny/app/app/Services/Crm/Bullhorn
/Users/lukas/jiminny/app/app/Notifications/Channels
/Users/lukas/jiminny/app/tests/Unit
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/Journal
/Users/lukas/jiminny/app/app/Interactions/Settings/Teams
/Users/lukas/jiminny/app/app/Exceptions/Crm
/Users/lukas/jiminny/app/vendor/hubspot/hubspot-php/src/Endpoints
/Users/lukas/jiminny/app/config
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/OpportunitySyncStrategy
/Users/lukas/jiminny/app/vendor/laravel/framework/src/Illuminate/Redis/Connections
/Users/lukas/jiminny/app/app/Http/Controllers/Settings/Teams
/Users/lukas/jiminny/app/app/Services/Crm/Hubspot/Webhook/Traits
/Users/lukas/jiminny/app/vendor/laravel/framework/src/Illuminate/Broadcasting
/Users/lukas/jiminny/app/app/Component/FeatureFlags
/Users/lukas/jiminny/app/app/Component/Activity
/Users/lukas/jiminny/app/app/Component/ActivitySearch
/Users/lukas/jiminny/app/tests/Unit/Events/Activities/Crm
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Hubspot/Pagination
/Users/lukas/jiminny/app/app/Console/Commands/Dev
/Users/lukas/jiminny/app/front-end
/Users/lukas/jiminny/app/app/Component/Prophet
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/IntegrationApp
/Users/lukas/jiminny/app/app/Component/AskAnything
/Users/lukas/jiminny/app/app/Component/AskJiminnyAi/OnDemandLevel/Events
/Users/lukas/jiminny/app/app/Component/AskAnything/Events
/Users/lukas/jiminny/app/app/Component/AskJiminnyAi/DealLevel/Traits
/Users/lukas/jiminny/app/app/Component/ProphetAi
/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/d1e2c340-64e9-49c6-aa9a-196201874532
/Users/lukas/jiminny/app/app/Http/Controllers/API/Page
/Users/lukas/jiminny/app/front-end/src/components/ondemand/ActivityList
/Users/lukas/Library/Application Support/JetBrains/PhpStorm2026.1/consoles/db/5b1549d5-9876-4d9e-9ce3-025f12a83283
/Users/lukas/jiminny/app/app/Contracts/Repositories
/Users/lukas/jiminny/app/app/Http/Controllers/Kiosk
/Users/lukas/jiminny/app/app/Component/AiAutomation/Actions
/Users/lukas/jiminny/app/app/Services/Activity/HubSpot
/Users/lukas/jiminny/app/app/Services/Crm/Pipedrive
/Users/lukas/jiminny/app/app/Jobs/Activity/Import
/Users/lukas/jiminny/app/app/Events/Import
/Users/lukas/jiminny/app/app/Events/Activities/Dialers
/Users/lukas/jiminny/app/tests
/Users/lukas/jiminny/app/app/Events/Activities
/Users/lukas/jiminny/app/tests/Unit/Jobs/Activity/PushSummaryToCrm
/Users/lukas/jiminny/app/app/Console/Commands/Analytics
/Users/lukas/jiminny/app/tests/Unit/Services/Kiosk/AutomatedReports
/Users/lukas/jiminny/app/app/Http/Middleware
/Users/lukas/jiminny/app/app/Http/Controllers/Auth
/Users/lukas/jiminny/app/tests/Unit/Jobs/Crm
/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp/Api
/Users/lukas/jiminny/app/app/Services/Crm/IntegrationApp/Accessors
/Users/lukas/jiminny/app/app/Services/Crm/Close
/Users/lukas/jiminny/app/app/Services
/Users/lukas/jiminny/app/app/Http/Transformers
/Users/lukas/jiminny/app/tests/Unit/Services/Crm/Pipedrive
/Users/lukas/jiminny/app/app/Listeners/Activities/Crm/Summary
/Users/lukas/jiminny/app/app/Services/Activity/AmazonConnect
/Users/lukas/jiminny/app/app/Models/Participant
/Users/lukas/jiminny/app/app/Events/Activities/Connections
/Users/lukas/jiminny/app/app/Listeners/Activities/Crm...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3643
|
134
|
15
|
2026-05-07T12:32:32.603482+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157152603_m2.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/…/SyncCrmEntitiesTrait.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"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":"Search Backward","depth":4,"bounds":{"left":0.7130984,"top":0.07821229,"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":"Search Forward","depth":4,"bounds":{"left":0.72174203,"top":0.07821229,"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":"Match сase","depth":4,"bounds":{"left":0.73038566,"top":0.07821229,"width":0.032247342,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"bounds":{"left":0.76263297,"top":0.07821229,"width":0.023271276,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"bounds":{"left":0.7859042,"top":0.07821229,"width":0.022938829,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"bounds":{"left":0.8088431,"top":0.08220271,"width":0.0019946808,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.97539896,"top":0.07821229,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","depth":4,"bounds":{"left":0.52859044,"top":0.016759777,"width":0.47140956,"height":0.98324025},"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","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":"62","depth":4,"bounds":{"left":0.48969415,"top":0.17478053,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"32","depth":4,"bounds":{"left":0.50199467,"top":0.17478053,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.17318435,"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.5212766,"top":0.17318435,"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\\ServiceTraits;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteAccountJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteContactJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteOpportunityJob;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\Hubspot\\HubspotClientInterface;\nuse Jiminny\\Services\\Crm\\Hubspot\\WebhookSyncBatchProcessor;\nuse Jiminny\\Utils\\StringUtil;\n\ntrait SyncCrmEntitiesTrait\n{\n use OpportunitySyncTrait;\n private const string CDN_URL = 'https://cdn2.hubspot.net/';\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private function getAssociationDataForCollection(array $collection, string $fromObject, string $toObject): array\n {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $hsOpportunityIds = array_column($collection, 'id');\n\n return $this->client->getAssociationsData($hsOpportunityIds, $fromObject, $toObject);\n }\n\n private function importAssociationData(array $collection, array $associatedData): array\n {\n $data = [];\n if (! empty($associatedData[$collection['id']])) {\n foreach ($associatedData[$collection['id']] as $id) {\n $data[] = [\n 'id' => $id,\n ];\n }\n }\n\n return ['results' => $data];\n }\n\n /**\n * Sync contacts modified since a given date (manual sync mode).\n *\n * This method fetches contacts from HubSpot API based on modification date and\n * imports them one by one. It is used for:\n * - Manual sync commands (e.g., crm:sync-contact with --from parameter)\n * - Initial sync for new teams\n * - Backfill operations\n *\n * For regular sync webhook batchSyncContacts is used:\n *\n * @param Carbon $since Fetch contacts modified after this date\n * @param Carbon|null $to Optional end date for modification range\n *\n * @return int Number of contacts successfully synced\n */\n public function syncContacts(Carbon $since, ?Carbon $to = null): int\n {\n $syncCount = 0;\n\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getContactFields();\n $payload = $this->payloadBuilder->getRecentlyUpdatedSearchPayload($since, $to, $fields);\n\n foreach ($this->client->getPaginatedDataGenerator($payload, 'contacts') as $hsContact) {\n $this->importContact($hsContact);\n $syncCount++;\n }\n } catch (Exception $exception) {\n $this->logger->error('[' . $this->getDisplayName() . '] Sync contacts failed', [\n 'teamId' => $this->team->getUuid(),\n 'reason' => $exception->getMessage(),\n ]);\n }\n\n return $syncCount;\n }\n\n /**\n * @inheritdoc\n */\n public function syncContact(string $crmId): ?Contact\n {\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getContactFields();\n $hsContact = $this->client->getContactById($crmId, $fields);\n } catch (\\HubSpot\\Client\\Crm\\Contacts\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact fetch failed', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n } catch (CrmException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n if (empty($hsContact['properties']) || empty($hsContact['id'])) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Contact data incomplete', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'has_properties' => ! empty($hsContact['properties']),\n 'has_id' => ! empty($hsContact['id']),\n ]);\n\n return null;\n }\n\n return $this->importContact($hsContact);\n }\n\n private function getContactFields(): array\n {\n return [\n 'associatedcompanyid',\n 'country',\n 'firstname',\n 'lastname',\n 'phone',\n 'mobilephone',\n 'email',\n 'photo',\n 'hs_avatar_filemanager_key',\n 'jobtitle',\n 'hubspot_owner_id',\n 'hs_object_id',\n 'createdate',\n 'hs_lastmodifieddate',\n ];\n }\n\n /**\n * @inheritdoc\n */\n private function importContact($crmData, array $accountMappings = []): ?Contact\n {\n $crmProviderId = $crmData['id'] ?? null;\n\n $this->logger->info('[HubSpot] importContact', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n if (empty($crmData['properties'])) {\n $this->logger->info('[HubSpot] importContact failed: empty properties', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return null;\n }\n\n $properties = $crmData['properties'];\n $crmId = (string) $crmData['id'];\n\n $accountId = $this->resolveContactAccount($properties, $accountMappings);\n $data = $this->buildContactData($crmId, $properties, $accountId);\n\n return $this->crmEntityRepository->importContact($this->config, $data);\n }\n\n private function resolveContactAccount(array $properties, array $accountMappings): ?int\n {\n if (empty($properties['associatedcompanyid'])) {\n return null;\n }\n\n $companyId = (string) $properties['associatedcompanyid'];\n\n if (! empty($accountMappings)) {\n return $accountMappings[$companyId] ?? null;\n }\n\n return $this->crmEntityRepository->findAccountByExternalId(\n $this->team->getCrmConfiguration(),\n $companyId\n )?->getId() ?? $this->syncAccount($companyId)?->getId();\n }\n\n private function buildContactData(string $crmId, array $properties, ?int $accountId): array\n {\n $countryCode = $this->buildContactCountry($properties);\n $name = $this->buildContactName($properties);\n $photoPath = $this->teamService->generateAvatar(\n $crmId,\n empty($name) ? ($properties['email'] ?? 'N/A') : $name,\n );\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n $mobileNumber = $this->buildContactMobilePhone($countryCode, $properties);\n\n $ownerId = $properties['hubspot_owner_id'] ?? null;\n $profile = $ownerId !== null\n ? $this->crmEntityRepository->findProfileByExternalId($this->config, (string) $ownerId)\n : null;\n\n $ext = (isset($parsedNumber['ext']) && is_string($parsedNumber['ext']) && strlen($parsedNumber['ext']) <= 10)\n ? $parsedNumber['ext']\n : null;\n\n $title = isset($properties['jobtitle']) ? mb_strimwidth($properties['jobtitle'], 0, 128) : null;\n $email = isset($properties['email']) ? mb_strimwidth($properties['email'], 0, 191) : null;\n $remotelyCreatedAt = ! empty($properties['createdate']) ? Carbon::parse($properties['createdate']) : null;\n\n return [\n 'crm_provider_id' => $crmId,\n 'team_id' => $this->team->getId(),\n 'account_id' => $accountId,\n 'user_id' => $profile?->getUserId(),\n 'owner_id' => $ownerId,\n 'name' => $name,\n 'title' => $title,\n 'email' => $email,\n 'country_code' => $countryCode,\n 'phone' => $parsedNumber['phone'] ?? null,\n 'mobile_phone' => $mobileNumber ?? null,\n 'ext' => $ext,\n 'photo_path' => $photoPath,\n 'remotely_created_at' => $remotelyCreatedAt,\n ];\n }\n\n /**\n * @param $properties\n */\n private function buildContactName($properties): string\n {\n if (is_array($properties)) {\n return $this->buildContactNameFromArray($properties);\n }\n\n return $this->buildContactNameFromObject($properties);\n }\n\n private function buildContactNameFromArray(array $properties): string\n {\n if (! empty($properties['name'])) {\n return mb_strimwidth($properties['name'], 0, 100);\n }\n\n $name = '';\n if (! empty($properties['firstname'])) {\n $name = $properties['firstname'] . ' ';\n }\n\n if (! empty($properties['lastname'])) {\n $name .= $properties['lastname'];\n }\n\n if ($name === '' && ! empty($properties['email'])) {\n $name = $properties['email'];\n }\n\n return mb_strimwidth($name, 0, 100);\n }\n\n private function buildContactNameFromObject($properties): string\n {\n $name = '';\n if (isset($properties->firstname)) {\n $name = $properties->firstname->value . ' ';\n }\n if (isset($properties->lastname)) {\n $name .= $properties->lastname->value;\n }\n if ($name === '' && isset($properties->email)) {\n $name = $properties->email->value;\n }\n\n return mb_strimwidth($name, 0, 100);\n }\n\n /**\n * @param $properties\n */\n private function buildContactPhone(?string $countryCode, $properties): ?array\n {\n if (is_array($properties) && empty($properties['phone']) === false) {\n $number = mb_strimwidth($properties['phone'], 0, 25);\n\n return parsePhoneNumber($countryCode, $number);\n } elseif (isset($properties->phone)) {\n $number = mb_strimwidth($properties->phone->value, 0, 25);\n\n return parsePhoneNumber($countryCode, $number);\n }\n\n return [];\n }\n\n /**\n * @param $properties\n */\n private function buildContactMobilePhone(?string $countryCode, $properties): ?string\n {\n return isset($properties['mobilephone'])\n ? Str::limit(phone_e164($countryCode, $properties['mobilephone']), 25, '')\n : null;\n }\n\n /**\n * @param $properties\n * @param $account\n */\n private function buildContactCountry($properties): ?string\n {\n if (is_array($properties) && empty($properties['country']) === false) {\n return $this->convertCountryNameToCode($properties['country']);\n }\n\n if (isset($properties->country)) {\n return $this->convertCountryNameToCode($properties->country->value);\n }\n\n return null;\n }\n\n /**\n * HubSpot doesn't have leads, so this method does nothing.\n *\n * @param Carbon $since\n * @param Carbon|null $to\n * @param string|null $crmProfileId\n *\n * @return int\n */\n public function syncLeads(Carbon $since, ?Carbon $to = null, ?string $crmProfileId = null): int\n {\n // Mark unused parameters to avoid code smell warnings\n unset($since, $to, $crmProfileId);\n\n return 0;\n }\n\n /**\n * HubSpot doesn't have leads.\n *\n * @param string $crmId\n *\n * @inheritdoc\n */\n public function syncLead(string $crmId): ?Lead\n {\n // Mark unused parameter to avoid code smell warnings\n unset($crmId);\n\n return null;\n }\n\n /**\n * Sync accounts (companies) modified since a given date (manual sync mode).\n *\n * This method fetches companies from HubSpot API based on modification date and\n * imports them one by one. It is used for:\n * - Manual sync commands (e.g., crm:sync-account with --from parameter)\n * - Initial sync for new teams\n * - Backfill operations\n *\n * For regular sync webhook batchSyncCompanies is used:\n *\n * @param Carbon $since Fetch companies modified after this date\n * @param Carbon|null $to Optional end date for modification range\n *\n * @return int Number of companies successfully synced\n */\n public function syncAccounts(Carbon $since, ?Carbon $to = null): int\n {\n $syncCount = 0;\n\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getCompanyFields();\n $payload = $this->payloadBuilder->getRecentlyUpdatedSearchPayload($since, $to, $fields);\n\n foreach ($this->client->getPaginatedDataGenerator($payload, 'companies') as $hsAccount) {\n $this->importAccount($hsAccount);\n $syncCount++;\n }\n } catch (Exception $exception) {\n $this->logger->error('[' . $this->getDisplayName() . '] Sync accounts failed', [\n 'teamId' => $this->team->getUuid(),\n 'reason' => $exception->getMessage(),\n ]);\n }\n\n return $syncCount;\n }\n\n /**\n * @inheritdoc\n */\n public function syncAccount(string $crmId): ?Account\n {\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getCompanyFields();\n $hsAccount = $this->client->getAccountById($crmId, $fields);\n } catch (\\HubSpot\\Client\\Crm\\Companies\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Account fetch failed', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n } catch (CrmException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Account not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n return $this->importAccount($hsAccount);\n }\n\n /**\n * Process webhook-collected contact batches.\n *\n * Drains Redis sets containing contact CRM IDs collected from webhook events\n * and dispatches ImportContactBatch jobs for batch processing.\n *\n * @return int Number of contact IDs dispatched to jobs\n */\n public function batchSyncContacts(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_CONTACT,\n $configId\n );\n }\n\n public function importContactBatchByIds(array $crmIds): array\n {\n $result = [\n 'success_count' => 0,\n 'failed_ids' => [],\n 'errors' => [],\n ];\n\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $batchStart = microtime(true);\n $slowContacts = [];\n\n $fetchStart = microtime(true);\n $allContacts = $this->fetchContactsByIdsInChunks($crmIds);\n $fetchMs = (int) round((microtime(true) - $fetchStart) * 1000);\n\n $fetchedIds = array_map('strval', array_column($allContacts, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact CRM IDs not found in HubSpot', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allContacts),\n ]);\n }\n\n if (empty($allContacts)) {\n return $result;\n }\n\n $prepareStart = microtime(true);\n $accountMappings = $this->prepareAccountMappingsForContacts($allContacts);\n $prepareAccountsMs = (int) round((microtime(true) - $prepareStart) * 1000);\n\n $loopStart = microtime(true);\n foreach ($allContacts as $contactData) {\n $contactStart = microtime(true);\n\n try {\n $contact = $this->importContact($contactData, $accountMappings);\n if ($contact !== null) {\n $result['success_count']++;\n }\n } catch (\\Throwable $e) {\n $crmId = $contactData['id'] ?? 'unknown';\n $result['failed_ids'][] = $crmId;\n $result['errors'][$crmId] = $e->getMessage();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import contact', [\n 'teamId' => $this->team->getId(),\n 'crmId' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n }\n\n $contactMs = (int) round((microtime(true) - $contactStart) * 1000);\n if ($contactMs > 1000) {\n $slowContacts[] = ['crmId' => $contactData['id'] ?? 'unknown', 'ms' => $contactMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importContactBatch timing', [\n 'teamId' => $this->team->getId(),\n 'contact_count' => \\count($allContacts),\n 'requested_count' => \\count($crmIds),\n 'not_found_count' => \\count($notFoundIds),\n 'total_ms' => $totalMs,\n 'fetch_api_ms' => $fetchMs,\n 'prepare_accounts_ms' => $prepareAccountsMs,\n 'contacts_loop_ms' => $loopMs,\n 'avg_contact_ms' => ! empty($allContacts) ? (int) round($loopMs / \\count($allContacts)) : 0,\n 'slow_contacts_count' => \\count($slowContacts),\n 'slow_contacts' => array_slice($slowContacts, 0, 10),\n ]);\n\n return $result;\n }\n\n private function fetchContactsByIdsInChunks(array $crmIds): array\n {\n $fields = $this->getContactFields();\n $allContacts = [];\n\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n try {\n $contacts = $this->client->getContactsByIds($chunk, $fields);\n foreach ($contacts as $contactData) {\n $allContacts[] = $contactData;\n }\n } catch (\\Throwable $e) {\n // @TODO what will happen if this exception is thrown\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch contact fetch failed', [\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $allContacts;\n }\n\n private function prepareAccountMappingsForContacts(array $contacts): array\n {\n $companyIds = [];\n foreach ($contacts as $contact) {\n $companyId = $contact['properties']['associatedcompanyid'] ?? null;\n if ($companyId !== null && $companyId !== '') {\n $companyIds[] = (string) $companyId;\n }\n }\n\n $companyIds = array_unique($companyIds);\n\n if (empty($companyIds)) {\n return [];\n }\n\n $mappings = $this->crmEntityRepository\n ->getExistingAccountIdsMap($this->config, $companyIds);\n\n $missingCompanyIds = array_diff($companyIds, array_keys($mappings));\n\n if (empty($missingCompanyIds)) {\n return $mappings;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing accounts for contacts', [\n 'teamId' => $this->team->getId(),\n 'total_companies' => \\count($companyIds),\n 'existing_companies' => \\count($mappings),\n 'missing_companies' => \\count($missingCompanyIds),\n ]);\n\n try {\n $syncedAccounts = $this->batchSyncAccountsForContacts($missingCompanyIds);\n $mappings = array_merge($mappings, $syncedAccounts);\n } catch (\\Throwable $e) {\n $this->logger->error('[' . $this->getDisplayName() . '] Failed to batch sync missing accounts', [\n 'teamId' => $this->team->getId(),\n 'missingCompanyIds' => $missingCompanyIds,\n 'missingCount' => count($missingCompanyIds),\n 'error' => $e->getMessage(),\n ]);\n }\n\n return $mappings;\n }\n\n private function batchSyncAccountsForContacts(array $companyIds): array\n {\n $syncedAccounts = [];\n $fields = $this->getCompanyFields();\n\n foreach (array_chunk($companyIds, self::BATCH_SIZE) as $chunk) {\n try {\n $companies = $this->client->getCompaniesByIds($chunk, $fields);\n\n foreach ($companies as $companyData) {\n try {\n $account = $this->importAccount($companyData);\n if ($account) {\n $syncedAccounts[$account->getCrmProviderId()] = $account->getId();\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import account in batch', [\n 'teamId' => $this->team->getId(),\n 'companyId' => $companyData['id'] ?? 'unknown',\n 'error' => $e->getMessage(),\n ]);\n }\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch company fetch failed', [\n 'teamId' => $this->team->getId(),\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n return $syncedAccounts;\n }\n\n /**\n * Process webhook-collected company batches.\n *\n * Drains Redis sets containing company CRM IDs collected from webhook events\n * and dispatches ImportAccountBatch jobs for batch processing.\n *\n * @return int Number of company IDs dispatched to jobs\n */\n public function batchSyncCompanies(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_COMPANY,\n $configId\n );\n }\n\n public function importAccountBatchByIds(array $crmIds): array\n {\n $result = [\n 'success_count' => 0,\n 'failed_ids' => [],\n 'errors' => [],\n ];\n\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $batchStart = microtime(true);\n $slowAccounts = [];\n\n $fields = $this->getCompanyFields();\n $allCompanies = [];\n\n $fetchStart = microtime(true);\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n try {\n $companies = $this->client->getCompaniesByIds($chunk, $fields);\n foreach ($companies as $companyData) {\n $allCompanies[] = $companyData;\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch company fetch failed', [\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n $fetchMs = (int) round((microtime(true) - $fetchStart) * 1000);\n\n $fetchedIds = array_map('strval', array_column($allCompanies, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Company CRM IDs not found in HubSpot', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allCompanies),\n ]);\n }\n\n $loopStart = microtime(true);\n foreach ($allCompanies as $companyData) {\n $accountStart = microtime(true);\n\n try {\n $account = $this->importAccount($companyData);\n if ($account !== null) {\n $result['success_count']++;\n }\n } catch (\\Throwable $e) {\n $crmId = $companyData['id'] ?? $companyData['properties']['hs_object_id'] ?? 'unknown';\n $result['failed_ids'][] = $crmId;\n $result['errors'][$crmId] = $e->getMessage();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import account', [\n 'crmId' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n }\n\n $accountMs = (int) round((microtime(true) - $accountStart) * 1000);\n if ($accountMs > 1000) {\n $crmId = $companyData['id'] ?? $companyData['properties']['hs_object_id'] ?? 'unknown';\n $slowAccounts[] = ['crmId' => $crmId, 'ms' => $accountMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importAccountBatch timing', [\n 'teamId' => $this->team->getId(),\n 'account_count' => \\count($allCompanies),\n 'requested_count' => \\count($crmIds),\n 'not_found_count' => \\count($notFoundIds),\n 'total_ms' => $totalMs,\n 'fetch_api_ms' => $fetchMs,\n 'accounts_loop_ms' => $loopMs,\n 'avg_account_ms' => ! empty($allCompanies) ? (int) round($loopMs / \\count($allCompanies)) : 0,\n 'slow_accounts_count' => \\count($slowAccounts),\n 'slow_accounts' => array_slice($slowAccounts, 0, 10),\n ]);\n\n return $result;\n }\n\n private function getCompanyFields(): array\n {\n return [\n 'country',\n 'name',\n 'phone',\n 'domain',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'hs_object_id',\n 'createdate',\n 'hs_lastmodifieddate',\n ];\n }\n\n private function importAccount($crmData): ?Account\n {\n $crmProviderId = $crmData['id'] ?? $crmData['properties']['hs_object_id'] ?? null;\n\n $this->logger->info('[HubSpot] importAccount', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n if (empty($crmData['properties'])) {\n $this->logger->info('[HubSpot] importAccount failed: empty properties', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return null;\n }\n\n $properties = $crmData['properties'];\n $crmId = (string) $properties['hs_object_id'];\n\n $countryCode = isset($properties['country']) ? $this->convertCountryNameToCode($properties['country']) : null;\n\n if (isset($properties['phone'])) {\n // Trim to our width and attempt to parse it.\n $number = mb_strimwidth($properties['phone'], 0, 25);\n $parsedNumber = parsePhoneNumber($countryCode, $number);\n } else {\n $parsedNumber = [];\n }\n\n $name = '[unknown]';\n if (isset($properties['name'])) {\n $name = $properties['name'];\n }\n\n $photoPath = $this->prospectPhotoPathService->getOrGeneratePhotoPath(\n $this->config,\n $crmId,\n Account::class,\n $crmId,\n $name\n );\n\n $industry = null;\n if (isset($properties['industry'])) {\n $industry = mb_strimwidth($properties['industry'], 0, 40);\n }\n\n $ownerId = $profile = null;\n if (isset($properties['hubspot_owner_id'])) {\n $ownerId = $properties['hubspot_owner_id'];\n $profile = $this->crmEntityRepository->findProfileByExternalId($this->config, (string) $ownerId);\n }\n\n $domain = null;\n if (isset($properties['domain'])) {\n $domain = StringUtil::resolveDomain($properties['domain']);\n }\n\n $remotelyCreatedAt = null;\n if (isset($properties['createdate']) && ! empty($properties['createdate'])) {\n $remotelyCreatedAt = Carbon::parse($properties['createdate']);\n }\n\n $data = [\n 'crm_provider_id' => $crmId,\n 'team_id' => $this->team->id,\n 'user_id' => $profile ? $profile->user_id : null,\n 'owner_id' => $ownerId,\n 'name' => mb_strimwidth($name, 0, 191),\n 'photo_path' => $photoPath,\n 'industry' => $industry,\n 'domain' => $domain !== null\n ? substr($domain, 0, 191)\n : null,\n 'phone' => $parsedNumber['phone'] ?? null,\n 'ext' => $parsedNumber['ext'] ?? null,\n 'country_code' => $countryCode,\n 'remotely_created_at' => $remotelyCreatedAt,\n ];\n\n return $this->crmEntityRepository->importAccount($this->config, $data);\n }\n\n public function deleteContact(string $crmProviderId): bool\n {\n try {\n $contact = $this->crmEntityRepository->findContactByExternalId($this->config, $crmProviderId);\n\n if (! $contact) {\n $this->logger->info('[HubSpot] Contact not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $contact->getId();\n\n $this->logger->info('[HubSpot] Deleting contact via webhook', [\n 'contact_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $contact->delete();\n DeleteContactJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete contact via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n public function deleteAccount(string $crmProviderId): bool\n {\n try {\n $account = $this->crmEntityRepository->findAccountByExternalId($this->config, $crmProviderId);\n\n if (! $account) {\n $this->logger->info('[HubSpot] Account not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $account->getId();\n\n $this->logger->info('[HubSpot] Deleting account via webhook', [\n 'account_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $account->delete();\n DeleteAccountJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete account via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n public function deleteOpportunity(string $crmProviderId): bool\n {\n try {\n $opportunity = $this->crmEntityRepository->findOpportunityByExternalId($this->config, $crmProviderId);\n\n if (! $opportunity) {\n $this->logger->info('[HubSpot] Opportunity not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $opportunity->getId();\n\n $this->logger->info('[HubSpot] Deleting opportunity via webhook', [\n 'opportunity_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $opportunity->delete();\n DeleteOpportunityJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete opportunity via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteAccountJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteContactJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteOpportunityJob;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\Hubspot\\HubspotClientInterface;\nuse Jiminny\\Services\\Crm\\Hubspot\\WebhookSyncBatchProcessor;\nuse Jiminny\\Utils\\StringUtil;\n\ntrait SyncCrmEntitiesTrait\n{\n use OpportunitySyncTrait;\n private const string CDN_URL = 'https://cdn2.hubspot.net/';\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private function getAssociationDataForCollection(array $collection, string $fromObject, string $toObject): array\n {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $hsOpportunityIds = array_column($collection, 'id');\n\n return $this->client->getAssociationsData($hsOpportunityIds, $fromObject, $toObject);\n }\n\n private function importAssociationData(array $collection, array $associatedData): array\n {\n $data = [];\n if (! empty($associatedData[$collection['id']])) {\n foreach ($associatedData[$collection['id']] as $id) {\n $data[] = [\n 'id' => $id,\n ];\n }\n }\n\n return ['results' => $data];\n }\n\n /**\n * Sync contacts modified since a given date (manual sync mode).\n *\n * This method fetches contacts from HubSpot API based on modification date and\n * imports them one by one. It is used for:\n * - Manual sync commands (e.g., crm:sync-contact with --from parameter)\n * - Initial sync for new teams\n * - Backfill operations\n *\n * For regular sync webhook batchSyncContacts is used:\n *\n * @param Carbon $since Fetch contacts modified after this date\n * @param Carbon|null $to Optional end date for modification range\n *\n * @return int Number of contacts successfully synced\n */\n public function syncContacts(Carbon $since, ?Carbon $to = null): int\n {\n $syncCount = 0;\n\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getContactFields();\n $payload = $this->payloadBuilder->getRecentlyUpdatedSearchPayload($since, $to, $fields);\n\n foreach ($this->client->getPaginatedDataGenerator($payload, 'contacts') as $hsContact) {\n $this->importContact($hsContact);\n $syncCount++;\n }\n } catch (Exception $exception) {\n $this->logger->error('[' . $this->getDisplayName() . '] Sync contacts failed', [\n 'teamId' => $this->team->getUuid(),\n 'reason' => $exception->getMessage(),\n ]);\n }\n\n return $syncCount;\n }\n\n /**\n * @inheritdoc\n */\n public function syncContact(string $crmId): ?Contact\n {\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getContactFields();\n $hsContact = $this->client->getContactById($crmId, $fields);\n } catch (\\HubSpot\\Client\\Crm\\Contacts\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact fetch failed', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n } catch (CrmException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n if (empty($hsContact['properties']) || empty($hsContact['id'])) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Contact data incomplete', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'has_properties' => ! empty($hsContact['properties']),\n 'has_id' => ! empty($hsContact['id']),\n ]);\n\n return null;\n }\n\n return $this->importContact($hsContact);\n }\n\n private function getContactFields(): array\n {\n return [\n 'associatedcompanyid',\n 'country',\n 'firstname',\n 'lastname',\n 'phone',\n 'mobilephone',\n 'email',\n 'photo',\n 'hs_avatar_filemanager_key',\n 'jobtitle',\n 'hubspot_owner_id',\n 'hs_object_id',\n 'createdate',\n 'hs_lastmodifieddate',\n ];\n }\n\n /**\n * @inheritdoc\n */\n private function importContact($crmData, array $accountMappings = []): ?Contact\n {\n $crmProviderId = $crmData['id'] ?? null;\n\n $this->logger->info('[HubSpot] importContact', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n if (empty($crmData['properties'])) {\n $this->logger->info('[HubSpot] importContact failed: empty properties', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return null;\n }\n\n $properties = $crmData['properties'];\n $crmId = (string) $crmData['id'];\n\n $accountId = $this->resolveContactAccount($properties, $accountMappings);\n $data = $this->buildContactData($crmId, $properties, $accountId);\n\n return $this->crmEntityRepository->importContact($this->config, $data);\n }\n\n private function resolveContactAccount(array $properties, array $accountMappings): ?int\n {\n if (empty($properties['associatedcompanyid'])) {\n return null;\n }\n\n $companyId = (string) $properties['associatedcompanyid'];\n\n if (! empty($accountMappings)) {\n return $accountMappings[$companyId] ?? null;\n }\n\n return $this->crmEntityRepository->findAccountByExternalId(\n $this->team->getCrmConfiguration(),\n $companyId\n )?->getId() ?? $this->syncAccount($companyId)?->getId();\n }\n\n private function buildContactData(string $crmId, array $properties, ?int $accountId): array\n {\n $countryCode = $this->buildContactCountry($properties);\n $name = $this->buildContactName($properties);\n $photoPath = $this->teamService->generateAvatar(\n $crmId,\n empty($name) ? ($properties['email'] ?? 'N/A') : $name,\n );\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n $mobileNumber = $this->buildContactMobilePhone($countryCode, $properties);\n\n $ownerId = $properties['hubspot_owner_id'] ?? null;\n $profile = $ownerId !== null\n ? $this->crmEntityRepository->findProfileByExternalId($this->config, (string) $ownerId)\n : null;\n\n $ext = (isset($parsedNumber['ext']) && is_string($parsedNumber['ext']) && strlen($parsedNumber['ext']) <= 10)\n ? $parsedNumber['ext']\n : null;\n\n $title = isset($properties['jobtitle']) ? mb_strimwidth($properties['jobtitle'], 0, 128) : null;\n $email = isset($properties['email']) ? mb_strimwidth($properties['email'], 0, 191) : null;\n $remotelyCreatedAt = ! empty($properties['createdate']) ? Carbon::parse($properties['createdate']) : null;\n\n return [\n 'crm_provider_id' => $crmId,\n 'team_id' => $this->team->getId(),\n 'account_id' => $accountId,\n 'user_id' => $profile?->getUserId(),\n 'owner_id' => $ownerId,\n 'name' => $name,\n 'title' => $title,\n 'email' => $email,\n 'country_code' => $countryCode,\n 'phone' => $parsedNumber['phone'] ?? null,\n 'mobile_phone' => $mobileNumber ?? null,\n 'ext' => $ext,\n 'photo_path' => $photoPath,\n 'remotely_created_at' => $remotelyCreatedAt,\n ];\n }\n\n /**\n * @param $properties\n */\n private function buildContactName($properties): string\n {\n if (is_array($properties)) {\n return $this->buildContactNameFromArray($properties);\n }\n\n return $this->buildContactNameFromObject($properties);\n }\n\n private function buildContactNameFromArray(array $properties): string\n {\n if (! empty($properties['name'])) {\n return mb_strimwidth($properties['name'], 0, 100);\n }\n\n $name = '';\n if (! empty($properties['firstname'])) {\n $name = $properties['firstname'] . ' ';\n }\n\n if (! empty($properties['lastname'])) {\n $name .= $properties['lastname'];\n }\n\n if ($name === '' && ! empty($properties['email'])) {\n $name = $properties['email'];\n }\n\n return mb_strimwidth($name, 0, 100);\n }\n\n private function buildContactNameFromObject($properties): string\n {\n $name = '';\n if (isset($properties->firstname)) {\n $name = $properties->firstname->value . ' ';\n }\n if (isset($properties->lastname)) {\n $name .= $properties->lastname->value;\n }\n if ($name === '' && isset($properties->email)) {\n $name = $properties->email->value;\n }\n\n return mb_strimwidth($name, 0, 100);\n }\n\n /**\n * @param $properties\n */\n private function buildContactPhone(?string $countryCode, $properties): ?array\n {\n if (is_array($properties) && empty($properties['phone']) === false) {\n $number = mb_strimwidth($properties['phone'], 0, 25);\n\n return parsePhoneNumber($countryCode, $number);\n } elseif (isset($properties->phone)) {\n $number = mb_strimwidth($properties->phone->value, 0, 25);\n\n return parsePhoneNumber($countryCode, $number);\n }\n\n return [];\n }\n\n /**\n * @param $properties\n */\n private function buildContactMobilePhone(?string $countryCode, $properties): ?string\n {\n return isset($properties['mobilephone'])\n ? Str::limit(phone_e164($countryCode, $properties['mobilephone']), 25, '')\n : null;\n }\n\n /**\n * @param $properties\n * @param $account\n */\n private function buildContactCountry($properties): ?string\n {\n if (is_array($properties) && empty($properties['country']) === false) {\n return $this->convertCountryNameToCode($properties['country']);\n }\n\n if (isset($properties->country)) {\n return $this->convertCountryNameToCode($properties->country->value);\n }\n\n return null;\n }\n\n /**\n * HubSpot doesn't have leads, so this method does nothing.\n *\n * @param Carbon $since\n * @param Carbon|null $to\n * @param string|null $crmProfileId\n *\n * @return int\n */\n public function syncLeads(Carbon $since, ?Carbon $to = null, ?string $crmProfileId = null): int\n {\n // Mark unused parameters to avoid code smell warnings\n unset($since, $to, $crmProfileId);\n\n return 0;\n }\n\n /**\n * HubSpot doesn't have leads.\n *\n * @param string $crmId\n *\n * @inheritdoc\n */\n public function syncLead(string $crmId): ?Lead\n {\n // Mark unused parameter to avoid code smell warnings\n unset($crmId);\n\n return null;\n }\n\n /**\n * Sync accounts (companies) modified since a given date (manual sync mode).\n *\n * This method fetches companies from HubSpot API based on modification date and\n * imports them one by one. It is used for:\n * - Manual sync commands (e.g., crm:sync-account with --from parameter)\n * - Initial sync for new teams\n * - Backfill operations\n *\n * For regular sync webhook batchSyncCompanies is used:\n *\n * @param Carbon $since Fetch companies modified after this date\n * @param Carbon|null $to Optional end date for modification range\n *\n * @return int Number of companies successfully synced\n */\n public function syncAccounts(Carbon $since, ?Carbon $to = null): int\n {\n $syncCount = 0;\n\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getCompanyFields();\n $payload = $this->payloadBuilder->getRecentlyUpdatedSearchPayload($since, $to, $fields);\n\n foreach ($this->client->getPaginatedDataGenerator($payload, 'companies') as $hsAccount) {\n $this->importAccount($hsAccount);\n $syncCount++;\n }\n } catch (Exception $exception) {\n $this->logger->error('[' . $this->getDisplayName() . '] Sync accounts failed', [\n 'teamId' => $this->team->getUuid(),\n 'reason' => $exception->getMessage(),\n ]);\n }\n\n return $syncCount;\n }\n\n /**\n * @inheritdoc\n */\n public function syncAccount(string $crmId): ?Account\n {\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getCompanyFields();\n $hsAccount = $this->client->getAccountById($crmId, $fields);\n } catch (\\HubSpot\\Client\\Crm\\Companies\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Account fetch failed', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n } catch (CrmException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Account not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n return $this->importAccount($hsAccount);\n }\n\n /**\n * Process webhook-collected contact batches.\n *\n * Drains Redis sets containing contact CRM IDs collected from webhook events\n * and dispatches ImportContactBatch jobs for batch processing.\n *\n * @return int Number of contact IDs dispatched to jobs\n */\n public function batchSyncContacts(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_CONTACT,\n $configId\n );\n }\n\n public function importContactBatchByIds(array $crmIds): array\n {\n $result = [\n 'success_count' => 0,\n 'failed_ids' => [],\n 'errors' => [],\n ];\n\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $batchStart = microtime(true);\n $slowContacts = [];\n\n $fetchStart = microtime(true);\n $allContacts = $this->fetchContactsByIdsInChunks($crmIds);\n $fetchMs = (int) round((microtime(true) - $fetchStart) * 1000);\n\n $fetchedIds = array_map('strval', array_column($allContacts, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact CRM IDs not found in HubSpot', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allContacts),\n ]);\n }\n\n if (empty($allContacts)) {\n return $result;\n }\n\n $prepareStart = microtime(true);\n $accountMappings = $this->prepareAccountMappingsForContacts($allContacts);\n $prepareAccountsMs = (int) round((microtime(true) - $prepareStart) * 1000);\n\n $loopStart = microtime(true);\n foreach ($allContacts as $contactData) {\n $contactStart = microtime(true);\n\n try {\n $contact = $this->importContact($contactData, $accountMappings);\n if ($contact !== null) {\n $result['success_count']++;\n }\n } catch (\\Throwable $e) {\n $crmId = $contactData['id'] ?? 'unknown';\n $result['failed_ids'][] = $crmId;\n $result['errors'][$crmId] = $e->getMessage();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import contact', [\n 'teamId' => $this->team->getId(),\n 'crmId' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n }\n\n $contactMs = (int) round((microtime(true) - $contactStart) * 1000);\n if ($contactMs > 1000) {\n $slowContacts[] = ['crmId' => $contactData['id'] ?? 'unknown', 'ms' => $contactMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importContactBatch timing', [\n 'teamId' => $this->team->getId(),\n 'contact_count' => \\count($allContacts),\n 'requested_count' => \\count($crmIds),\n 'not_found_count' => \\count($notFoundIds),\n 'total_ms' => $totalMs,\n 'fetch_api_ms' => $fetchMs,\n 'prepare_accounts_ms' => $prepareAccountsMs,\n 'contacts_loop_ms' => $loopMs,\n 'avg_contact_ms' => ! empty($allContacts) ? (int) round($loopMs / \\count($allContacts)) : 0,\n 'slow_contacts_count' => \\count($slowContacts),\n 'slow_contacts' => array_slice($slowContacts, 0, 10),\n ]);\n\n return $result;\n }\n\n private function fetchContactsByIdsInChunks(array $crmIds): array\n {\n $fields = $this->getContactFields();\n $allContacts = [];\n\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n try {\n $contacts = $this->client->getContactsByIds($chunk, $fields);\n foreach ($contacts as $contactData) {\n $allContacts[] = $contactData;\n }\n } catch (\\Throwable $e) {\n // @TODO what will happen if this exception is thrown\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch contact fetch failed', [\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $allContacts;\n }\n\n private function prepareAccountMappingsForContacts(array $contacts): array\n {\n $companyIds = [];\n foreach ($contacts as $contact) {\n $companyId = $contact['properties']['associatedcompanyid'] ?? null;\n if ($companyId !== null && $companyId !== '') {\n $companyIds[] = (string) $companyId;\n }\n }\n\n $companyIds = array_unique($companyIds);\n\n if (empty($companyIds)) {\n return [];\n }\n\n $mappings = $this->crmEntityRepository\n ->getExistingAccountIdsMap($this->config, $companyIds);\n\n $missingCompanyIds = array_diff($companyIds, array_keys($mappings));\n\n if (empty($missingCompanyIds)) {\n return $mappings;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing accounts for contacts', [\n 'teamId' => $this->team->getId(),\n 'total_companies' => \\count($companyIds),\n 'existing_companies' => \\count($mappings),\n 'missing_companies' => \\count($missingCompanyIds),\n ]);\n\n try {\n $syncedAccounts = $this->batchSyncAccountsForContacts($missingCompanyIds);\n $mappings = array_merge($mappings, $syncedAccounts);\n } catch (\\Throwable $e) {\n $this->logger->error('[' . $this->getDisplayName() . '] Failed to batch sync missing accounts', [\n 'teamId' => $this->team->getId(),\n 'missingCompanyIds' => $missingCompanyIds,\n 'missingCount' => count($missingCompanyIds),\n 'error' => $e->getMessage(),\n ]);\n }\n\n return $mappings;\n }\n\n private function batchSyncAccountsForContacts(array $companyIds): array\n {\n $syncedAccounts = [];\n $fields = $this->getCompanyFields();\n\n foreach (array_chunk($companyIds, self::BATCH_SIZE) as $chunk) {\n try {\n $companies = $this->client->getCompaniesByIds($chunk, $fields);\n\n foreach ($companies as $companyData) {\n try {\n $account = $this->importAccount($companyData);\n if ($account) {\n $syncedAccounts[$account->getCrmProviderId()] = $account->getId();\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import account in batch', [\n 'teamId' => $this->team->getId(),\n 'companyId' => $companyData['id'] ?? 'unknown',\n 'error' => $e->getMessage(),\n ]);\n }\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch company fetch failed', [\n 'teamId' => $this->team->getId(),\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n return $syncedAccounts;\n }\n\n /**\n * Process webhook-collected company batches.\n *\n * Drains Redis sets containing company CRM IDs collected from webhook events\n * and dispatches ImportAccountBatch jobs for batch processing.\n *\n * @return int Number of company IDs dispatched to jobs\n */\n public function batchSyncCompanies(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_COMPANY,\n $configId\n );\n }\n\n public function importAccountBatchByIds(array $crmIds): array\n {\n $result = [\n 'success_count' => 0,\n 'failed_ids' => [],\n 'errors' => [],\n ];\n\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $batchStart = microtime(true);\n $slowAccounts = [];\n\n $fields = $this->getCompanyFields();\n $allCompanies = [];\n\n $fetchStart = microtime(true);\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n try {\n $companies = $this->client->getCompaniesByIds($chunk, $fields);\n foreach ($companies as $companyData) {\n $allCompanies[] = $companyData;\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch company fetch failed', [\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n $fetchMs = (int) round((microtime(true) - $fetchStart) * 1000);\n\n $fetchedIds = array_map('strval', array_column($allCompanies, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Company CRM IDs not found in HubSpot', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allCompanies),\n ]);\n }\n\n $loopStart = microtime(true);\n foreach ($allCompanies as $companyData) {\n $accountStart = microtime(true);\n\n try {\n $account = $this->importAccount($companyData);\n if ($account !== null) {\n $result['success_count']++;\n }\n } catch (\\Throwable $e) {\n $crmId = $companyData['id'] ?? $companyData['properties']['hs_object_id'] ?? 'unknown';\n $result['failed_ids'][] = $crmId;\n $result['errors'][$crmId] = $e->getMessage();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import account', [\n 'crmId' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n }\n\n $accountMs = (int) round((microtime(true) - $accountStart) * 1000);\n if ($accountMs > 1000) {\n $crmId = $companyData['id'] ?? $companyData['properties']['hs_object_id'] ?? 'unknown';\n $slowAccounts[] = ['crmId' => $crmId, 'ms' => $accountMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importAccountBatch timing', [\n 'teamId' => $this->team->getId(),\n 'account_count' => \\count($allCompanies),\n 'requested_count' => \\count($crmIds),\n 'not_found_count' => \\count($notFoundIds),\n 'total_ms' => $totalMs,\n 'fetch_api_ms' => $fetchMs,\n 'accounts_loop_ms' => $loopMs,\n 'avg_account_ms' => ! empty($allCompanies) ? (int) round($loopMs / \\count($allCompanies)) : 0,\n 'slow_accounts_count' => \\count($slowAccounts),\n 'slow_accounts' => array_slice($slowAccounts, 0, 10),\n ]);\n\n return $result;\n }\n\n private function getCompanyFields(): array\n {\n return [\n 'country',\n 'name',\n 'phone',\n 'domain',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'hs_object_id',\n 'createdate',\n 'hs_lastmodifieddate',\n ];\n }\n\n private function importAccount($crmData): ?Account\n {\n $crmProviderId = $crmData['id'] ?? $crmData['properties']['hs_object_id'] ?? null;\n\n $this->logger->info('[HubSpot] importAccount', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n if (empty($crmData['properties'])) {\n $this->logger->info('[HubSpot] importAccount failed: empty properties', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return null;\n }\n\n $properties = $crmData['properties'];\n $crmId = (string) $properties['hs_object_id'];\n\n $countryCode = isset($properties['country']) ? $this->convertCountryNameToCode($properties['country']) : null;\n\n if (isset($properties['phone'])) {\n // Trim to our width and attempt to parse it.\n $number = mb_strimwidth($properties['phone'], 0, 25);\n $parsedNumber = parsePhoneNumber($countryCode, $number);\n } else {\n $parsedNumber = [];\n }\n\n $name = '[unknown]';\n if (isset($properties['name'])) {\n $name = $properties['name'];\n }\n\n $photoPath = $this->prospectPhotoPathService->getOrGeneratePhotoPath(\n $this->config,\n $crmId,\n Account::class,\n $crmId,\n $name\n );\n\n $industry = null;\n if (isset($properties['industry'])) {\n $industry = mb_strimwidth($properties['industry'], 0, 40);\n }\n\n $ownerId = $profile = null;\n if (isset($properties['hubspot_owner_id'])) {\n $ownerId = $properties['hubspot_owner_id'];\n $profile = $this->crmEntityRepository->findProfileByExternalId($this->config, (string) $ownerId);\n }\n\n $domain = null;\n if (isset($properties['domain'])) {\n $domain = StringUtil::resolveDomain($properties['domain']);\n }\n\n $remotelyCreatedAt = null;\n if (isset($properties['createdate']) && ! empty($properties['createdate'])) {\n $remotelyCreatedAt = Carbon::parse($properties['createdate']);\n }\n\n $data = [\n 'crm_provider_id' => $crmId,\n 'team_id' => $this->team->id,\n 'user_id' => $profile ? $profile->user_id : null,\n 'owner_id' => $ownerId,\n 'name' => mb_strimwidth($name, 0, 191),\n 'photo_path' => $photoPath,\n 'industry' => $industry,\n 'domain' => $domain !== null\n ? substr($domain, 0, 191)\n : null,\n 'phone' => $parsedNumber['phone'] ?? null,\n 'ext' => $parsedNumber['ext'] ?? null,\n 'country_code' => $countryCode,\n 'remotely_created_at' => $remotelyCreatedAt,\n ];\n\n return $this->crmEntityRepository->importAccount($this->config, $data);\n }\n\n public function deleteContact(string $crmProviderId): bool\n {\n try {\n $contact = $this->crmEntityRepository->findContactByExternalId($this->config, $crmProviderId);\n\n if (! $contact) {\n $this->logger->info('[HubSpot] Contact not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $contact->getId();\n\n $this->logger->info('[HubSpot] Deleting contact via webhook', [\n 'contact_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $contact->delete();\n DeleteContactJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete contact via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n public function deleteAccount(string $crmProviderId): bool\n {\n try {\n $account = $this->crmEntityRepository->findAccountByExternalId($this->config, $crmProviderId);\n\n if (! $account) {\n $this->logger->info('[HubSpot] Account not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $account->getId();\n\n $this->logger->info('[HubSpot] Deleting account via webhook', [\n 'account_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $account->delete();\n DeleteAccountJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete account via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n public function deleteOpportunity(string $crmProviderId): bool\n {\n try {\n $opportunity = $this->crmEntityRepository->findOpportunityByExternalId($this->config, $crmProviderId);\n\n if (! $opportunity) {\n $this->logger->info('[HubSpot] Opportunity not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $opportunity->getId();\n\n $this->logger->info('[HubSpot] Deleting opportunity via webhook', [\n 'opportunity_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $opportunity->delete();\n DeleteOpportunityJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete opportunity via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\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}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
3641
|
NULL
|
NULL
|
NULL
|
|
3642
|
133
|
9
|
2026-05-07T12:32:32.505237+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157152505_m1.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/…/SyncCrmEntitiesTrait.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"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":"Hubspot","depth":4,"on_screen":true,"value":"Hubspot","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":"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":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search All","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Backward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Forward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match сase","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"on_screen":true,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring start {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32:12] local.NOTICE: Monitoring end {\"correlation_id\":\"0be593b8-0aea-40cb-8dc9-1e74bb44ede1\",\"trace_id\":\"1537b6d8-4150-4d77-b2c6-9cec45a0374b\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32: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\":\"32c250b0-69ea-4669-98ae-b965a9479044\",\"trace_id\":\"d5d62398-e8b5-4dc7-96f0-4d945c921e2d\"}\n[2026-05-07 12:32:19] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32:19] 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\":\"edb12a01-c838-40ef-951d-413e5028f245\",\"trace_id\":\"00c83a82-64a6-40f5-a968-cdad57cd710a\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:23] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:30:00, 2026-05-07 12:32:00] {\"correlation_id\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32: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\":\"6749c715-7af6-4627-9ae9-566e158f698b\",\"trace_id\":\"76a70eba-ce35-4687-8705-48f62f076201\"}\n[2026-05-07 12:32:25] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:create\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] STARTING batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] local.INFO: [EmailSchedule] FINISHED batch create {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:25] 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\":\"3fa722f4-e215-4794-a480-060a0542c380\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}\n[2026-05-07 12:32:27] local.INFO: [Jiminny\\Jobs\\Mailbox\\CreateBatches] processed 2 inboxes and created 0 batches {\"userId\":null,\"batchSize\":30,\"maxBatches\":1000} {\"correlation_id\":\"7ae3582d-c6f0-4d3f-a055-768d0b080b2a\",\"trace_id\":\"8479ed65-dc02-43c7-908c-57d9365ba83e\"}","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":"62","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"32","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\\ServiceTraits;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteAccountJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteContactJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteOpportunityJob;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\Hubspot\\HubspotClientInterface;\nuse Jiminny\\Services\\Crm\\Hubspot\\WebhookSyncBatchProcessor;\nuse Jiminny\\Utils\\StringUtil;\n\ntrait SyncCrmEntitiesTrait\n{\n use OpportunitySyncTrait;\n private const string CDN_URL = 'https://cdn2.hubspot.net/';\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private function getAssociationDataForCollection(array $collection, string $fromObject, string $toObject): array\n {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $hsOpportunityIds = array_column($collection, 'id');\n\n return $this->client->getAssociationsData($hsOpportunityIds, $fromObject, $toObject);\n }\n\n private function importAssociationData(array $collection, array $associatedData): array\n {\n $data = [];\n if (! empty($associatedData[$collection['id']])) {\n foreach ($associatedData[$collection['id']] as $id) {\n $data[] = [\n 'id' => $id,\n ];\n }\n }\n\n return ['results' => $data];\n }\n\n /**\n * Sync contacts modified since a given date (manual sync mode).\n *\n * This method fetches contacts from HubSpot API based on modification date and\n * imports them one by one. It is used for:\n * - Manual sync commands (e.g., crm:sync-contact with --from parameter)\n * - Initial sync for new teams\n * - Backfill operations\n *\n * For regular sync webhook batchSyncContacts is used:\n *\n * @param Carbon $since Fetch contacts modified after this date\n * @param Carbon|null $to Optional end date for modification range\n *\n * @return int Number of contacts successfully synced\n */\n public function syncContacts(Carbon $since, ?Carbon $to = null): int\n {\n $syncCount = 0;\n\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getContactFields();\n $payload = $this->payloadBuilder->getRecentlyUpdatedSearchPayload($since, $to, $fields);\n\n foreach ($this->client->getPaginatedDataGenerator($payload, 'contacts') as $hsContact) {\n $this->importContact($hsContact);\n $syncCount++;\n }\n } catch (Exception $exception) {\n $this->logger->error('[' . $this->getDisplayName() . '] Sync contacts failed', [\n 'teamId' => $this->team->getUuid(),\n 'reason' => $exception->getMessage(),\n ]);\n }\n\n return $syncCount;\n }\n\n /**\n * @inheritdoc\n */\n public function syncContact(string $crmId): ?Contact\n {\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getContactFields();\n $hsContact = $this->client->getContactById($crmId, $fields);\n } catch (\\HubSpot\\Client\\Crm\\Contacts\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact fetch failed', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n } catch (CrmException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n if (empty($hsContact['properties']) || empty($hsContact['id'])) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Contact data incomplete', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'has_properties' => ! empty($hsContact['properties']),\n 'has_id' => ! empty($hsContact['id']),\n ]);\n\n return null;\n }\n\n return $this->importContact($hsContact);\n }\n\n private function getContactFields(): array\n {\n return [\n 'associatedcompanyid',\n 'country',\n 'firstname',\n 'lastname',\n 'phone',\n 'mobilephone',\n 'email',\n 'photo',\n 'hs_avatar_filemanager_key',\n 'jobtitle',\n 'hubspot_owner_id',\n 'hs_object_id',\n 'createdate',\n 'hs_lastmodifieddate',\n ];\n }\n\n /**\n * @inheritdoc\n */\n private function importContact($crmData, array $accountMappings = []): ?Contact\n {\n $crmProviderId = $crmData['id'] ?? null;\n\n $this->logger->info('[HubSpot] importContact', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n if (empty($crmData['properties'])) {\n $this->logger->info('[HubSpot] importContact failed: empty properties', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return null;\n }\n\n $properties = $crmData['properties'];\n $crmId = (string) $crmData['id'];\n\n $accountId = $this->resolveContactAccount($properties, $accountMappings);\n $data = $this->buildContactData($crmId, $properties, $accountId);\n\n return $this->crmEntityRepository->importContact($this->config, $data);\n }\n\n private function resolveContactAccount(array $properties, array $accountMappings): ?int\n {\n if (empty($properties['associatedcompanyid'])) {\n return null;\n }\n\n $companyId = (string) $properties['associatedcompanyid'];\n\n if (! empty($accountMappings)) {\n return $accountMappings[$companyId] ?? null;\n }\n\n return $this->crmEntityRepository->findAccountByExternalId(\n $this->team->getCrmConfiguration(),\n $companyId\n )?->getId() ?? $this->syncAccount($companyId)?->getId();\n }\n\n private function buildContactData(string $crmId, array $properties, ?int $accountId): array\n {\n $countryCode = $this->buildContactCountry($properties);\n $name = $this->buildContactName($properties);\n $photoPath = $this->teamService->generateAvatar(\n $crmId,\n empty($name) ? ($properties['email'] ?? 'N/A') : $name,\n );\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n $mobileNumber = $this->buildContactMobilePhone($countryCode, $properties);\n\n $ownerId = $properties['hubspot_owner_id'] ?? null;\n $profile = $ownerId !== null\n ? $this->crmEntityRepository->findProfileByExternalId($this->config, (string) $ownerId)\n : null;\n\n $ext = (isset($parsedNumber['ext']) && is_string($parsedNumber['ext']) && strlen($parsedNumber['ext']) <= 10)\n ? $parsedNumber['ext']\n : null;\n\n $title = isset($properties['jobtitle']) ? mb_strimwidth($properties['jobtitle'], 0, 128) : null;\n $email = isset($properties['email']) ? mb_strimwidth($properties['email'], 0, 191) : null;\n $remotelyCreatedAt = ! empty($properties['createdate']) ? Carbon::parse($properties['createdate']) : null;\n\n return [\n 'crm_provider_id' => $crmId,\n 'team_id' => $this->team->getId(),\n 'account_id' => $accountId,\n 'user_id' => $profile?->getUserId(),\n 'owner_id' => $ownerId,\n 'name' => $name,\n 'title' => $title,\n 'email' => $email,\n 'country_code' => $countryCode,\n 'phone' => $parsedNumber['phone'] ?? null,\n 'mobile_phone' => $mobileNumber ?? null,\n 'ext' => $ext,\n 'photo_path' => $photoPath,\n 'remotely_created_at' => $remotelyCreatedAt,\n ];\n }\n\n /**\n * @param $properties\n */\n private function buildContactName($properties): string\n {\n if (is_array($properties)) {\n return $this->buildContactNameFromArray($properties);\n }\n\n return $this->buildContactNameFromObject($properties);\n }\n\n private function buildContactNameFromArray(array $properties): string\n {\n if (! empty($properties['name'])) {\n return mb_strimwidth($properties['name'], 0, 100);\n }\n\n $name = '';\n if (! empty($properties['firstname'])) {\n $name = $properties['firstname'] . ' ';\n }\n\n if (! empty($properties['lastname'])) {\n $name .= $properties['lastname'];\n }\n\n if ($name === '' && ! empty($properties['email'])) {\n $name = $properties['email'];\n }\n\n return mb_strimwidth($name, 0, 100);\n }\n\n private function buildContactNameFromObject($properties): string\n {\n $name = '';\n if (isset($properties->firstname)) {\n $name = $properties->firstname->value . ' ';\n }\n if (isset($properties->lastname)) {\n $name .= $properties->lastname->value;\n }\n if ($name === '' && isset($properties->email)) {\n $name = $properties->email->value;\n }\n\n return mb_strimwidth($name, 0, 100);\n }\n\n /**\n * @param $properties\n */\n private function buildContactPhone(?string $countryCode, $properties): ?array\n {\n if (is_array($properties) && empty($properties['phone']) === false) {\n $number = mb_strimwidth($properties['phone'], 0, 25);\n\n return parsePhoneNumber($countryCode, $number);\n } elseif (isset($properties->phone)) {\n $number = mb_strimwidth($properties->phone->value, 0, 25);\n\n return parsePhoneNumber($countryCode, $number);\n }\n\n return [];\n }\n\n /**\n * @param $properties\n */\n private function buildContactMobilePhone(?string $countryCode, $properties): ?string\n {\n return isset($properties['mobilephone'])\n ? Str::limit(phone_e164($countryCode, $properties['mobilephone']), 25, '')\n : null;\n }\n\n /**\n * @param $properties\n * @param $account\n */\n private function buildContactCountry($properties): ?string\n {\n if (is_array($properties) && empty($properties['country']) === false) {\n return $this->convertCountryNameToCode($properties['country']);\n }\n\n if (isset($properties->country)) {\n return $this->convertCountryNameToCode($properties->country->value);\n }\n\n return null;\n }\n\n /**\n * HubSpot doesn't have leads, so this method does nothing.\n *\n * @param Carbon $since\n * @param Carbon|null $to\n * @param string|null $crmProfileId\n *\n * @return int\n */\n public function syncLeads(Carbon $since, ?Carbon $to = null, ?string $crmProfileId = null): int\n {\n // Mark unused parameters to avoid code smell warnings\n unset($since, $to, $crmProfileId);\n\n return 0;\n }\n\n /**\n * HubSpot doesn't have leads.\n *\n * @param string $crmId\n *\n * @inheritdoc\n */\n public function syncLead(string $crmId): ?Lead\n {\n // Mark unused parameter to avoid code smell warnings\n unset($crmId);\n\n return null;\n }\n\n /**\n * Sync accounts (companies) modified since a given date (manual sync mode).\n *\n * This method fetches companies from HubSpot API based on modification date and\n * imports them one by one. It is used for:\n * - Manual sync commands (e.g., crm:sync-account with --from parameter)\n * - Initial sync for new teams\n * - Backfill operations\n *\n * For regular sync webhook batchSyncCompanies is used:\n *\n * @param Carbon $since Fetch companies modified after this date\n * @param Carbon|null $to Optional end date for modification range\n *\n * @return int Number of companies successfully synced\n */\n public function syncAccounts(Carbon $since, ?Carbon $to = null): int\n {\n $syncCount = 0;\n\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getCompanyFields();\n $payload = $this->payloadBuilder->getRecentlyUpdatedSearchPayload($since, $to, $fields);\n\n foreach ($this->client->getPaginatedDataGenerator($payload, 'companies') as $hsAccount) {\n $this->importAccount($hsAccount);\n $syncCount++;\n }\n } catch (Exception $exception) {\n $this->logger->error('[' . $this->getDisplayName() . '] Sync accounts failed', [\n 'teamId' => $this->team->getUuid(),\n 'reason' => $exception->getMessage(),\n ]);\n }\n\n return $syncCount;\n }\n\n /**\n * @inheritdoc\n */\n public function syncAccount(string $crmId): ?Account\n {\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getCompanyFields();\n $hsAccount = $this->client->getAccountById($crmId, $fields);\n } catch (\\HubSpot\\Client\\Crm\\Companies\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Account fetch failed', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n } catch (CrmException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Account not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n return $this->importAccount($hsAccount);\n }\n\n /**\n * Process webhook-collected contact batches.\n *\n * Drains Redis sets containing contact CRM IDs collected from webhook events\n * and dispatches ImportContactBatch jobs for batch processing.\n *\n * @return int Number of contact IDs dispatched to jobs\n */\n public function batchSyncContacts(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_CONTACT,\n $configId\n );\n }\n\n public function importContactBatchByIds(array $crmIds): array\n {\n $result = [\n 'success_count' => 0,\n 'failed_ids' => [],\n 'errors' => [],\n ];\n\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $batchStart = microtime(true);\n $slowContacts = [];\n\n $fetchStart = microtime(true);\n $allContacts = $this->fetchContactsByIdsInChunks($crmIds);\n $fetchMs = (int) round((microtime(true) - $fetchStart) * 1000);\n\n $fetchedIds = array_map('strval', array_column($allContacts, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact CRM IDs not found in HubSpot', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allContacts),\n ]);\n }\n\n if (empty($allContacts)) {\n return $result;\n }\n\n $prepareStart = microtime(true);\n $accountMappings = $this->prepareAccountMappingsForContacts($allContacts);\n $prepareAccountsMs = (int) round((microtime(true) - $prepareStart) * 1000);\n\n $loopStart = microtime(true);\n foreach ($allContacts as $contactData) {\n $contactStart = microtime(true);\n\n try {\n $contact = $this->importContact($contactData, $accountMappings);\n if ($contact !== null) {\n $result['success_count']++;\n }\n } catch (\\Throwable $e) {\n $crmId = $contactData['id'] ?? 'unknown';\n $result['failed_ids'][] = $crmId;\n $result['errors'][$crmId] = $e->getMessage();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import contact', [\n 'teamId' => $this->team->getId(),\n 'crmId' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n }\n\n $contactMs = (int) round((microtime(true) - $contactStart) * 1000);\n if ($contactMs > 1000) {\n $slowContacts[] = ['crmId' => $contactData['id'] ?? 'unknown', 'ms' => $contactMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importContactBatch timing', [\n 'teamId' => $this->team->getId(),\n 'contact_count' => \\count($allContacts),\n 'requested_count' => \\count($crmIds),\n 'not_found_count' => \\count($notFoundIds),\n 'total_ms' => $totalMs,\n 'fetch_api_ms' => $fetchMs,\n 'prepare_accounts_ms' => $prepareAccountsMs,\n 'contacts_loop_ms' => $loopMs,\n 'avg_contact_ms' => ! empty($allContacts) ? (int) round($loopMs / \\count($allContacts)) : 0,\n 'slow_contacts_count' => \\count($slowContacts),\n 'slow_contacts' => array_slice($slowContacts, 0, 10),\n ]);\n\n return $result;\n }\n\n private function fetchContactsByIdsInChunks(array $crmIds): array\n {\n $fields = $this->getContactFields();\n $allContacts = [];\n\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n try {\n $contacts = $this->client->getContactsByIds($chunk, $fields);\n foreach ($contacts as $contactData) {\n $allContacts[] = $contactData;\n }\n } catch (\\Throwable $e) {\n // @TODO what will happen if this exception is thrown\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch contact fetch failed', [\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $allContacts;\n }\n\n private function prepareAccountMappingsForContacts(array $contacts): array\n {\n $companyIds = [];\n foreach ($contacts as $contact) {\n $companyId = $contact['properties']['associatedcompanyid'] ?? null;\n if ($companyId !== null && $companyId !== '') {\n $companyIds[] = (string) $companyId;\n }\n }\n\n $companyIds = array_unique($companyIds);\n\n if (empty($companyIds)) {\n return [];\n }\n\n $mappings = $this->crmEntityRepository\n ->getExistingAccountIdsMap($this->config, $companyIds);\n\n $missingCompanyIds = array_diff($companyIds, array_keys($mappings));\n\n if (empty($missingCompanyIds)) {\n return $mappings;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing accounts for contacts', [\n 'teamId' => $this->team->getId(),\n 'total_companies' => \\count($companyIds),\n 'existing_companies' => \\count($mappings),\n 'missing_companies' => \\count($missingCompanyIds),\n ]);\n\n try {\n $syncedAccounts = $this->batchSyncAccountsForContacts($missingCompanyIds);\n $mappings = array_merge($mappings, $syncedAccounts);\n } catch (\\Throwable $e) {\n $this->logger->error('[' . $this->getDisplayName() . '] Failed to batch sync missing accounts', [\n 'teamId' => $this->team->getId(),\n 'missingCompanyIds' => $missingCompanyIds,\n 'missingCount' => count($missingCompanyIds),\n 'error' => $e->getMessage(),\n ]);\n }\n\n return $mappings;\n }\n\n private function batchSyncAccountsForContacts(array $companyIds): array\n {\n $syncedAccounts = [];\n $fields = $this->getCompanyFields();\n\n foreach (array_chunk($companyIds, self::BATCH_SIZE) as $chunk) {\n try {\n $companies = $this->client->getCompaniesByIds($chunk, $fields);\n\n foreach ($companies as $companyData) {\n try {\n $account = $this->importAccount($companyData);\n if ($account) {\n $syncedAccounts[$account->getCrmProviderId()] = $account->getId();\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import account in batch', [\n 'teamId' => $this->team->getId(),\n 'companyId' => $companyData['id'] ?? 'unknown',\n 'error' => $e->getMessage(),\n ]);\n }\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch company fetch failed', [\n 'teamId' => $this->team->getId(),\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n return $syncedAccounts;\n }\n\n /**\n * Process webhook-collected company batches.\n *\n * Drains Redis sets containing company CRM IDs collected from webhook events\n * and dispatches ImportAccountBatch jobs for batch processing.\n *\n * @return int Number of company IDs dispatched to jobs\n */\n public function batchSyncCompanies(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_COMPANY,\n $configId\n );\n }\n\n public function importAccountBatchByIds(array $crmIds): array\n {\n $result = [\n 'success_count' => 0,\n 'failed_ids' => [],\n 'errors' => [],\n ];\n\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $batchStart = microtime(true);\n $slowAccounts = [];\n\n $fields = $this->getCompanyFields();\n $allCompanies = [];\n\n $fetchStart = microtime(true);\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n try {\n $companies = $this->client->getCompaniesByIds($chunk, $fields);\n foreach ($companies as $companyData) {\n $allCompanies[] = $companyData;\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch company fetch failed', [\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n $fetchMs = (int) round((microtime(true) - $fetchStart) * 1000);\n\n $fetchedIds = array_map('strval', array_column($allCompanies, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Company CRM IDs not found in HubSpot', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allCompanies),\n ]);\n }\n\n $loopStart = microtime(true);\n foreach ($allCompanies as $companyData) {\n $accountStart = microtime(true);\n\n try {\n $account = $this->importAccount($companyData);\n if ($account !== null) {\n $result['success_count']++;\n }\n } catch (\\Throwable $e) {\n $crmId = $companyData['id'] ?? $companyData['properties']['hs_object_id'] ?? 'unknown';\n $result['failed_ids'][] = $crmId;\n $result['errors'][$crmId] = $e->getMessage();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import account', [\n 'crmId' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n }\n\n $accountMs = (int) round((microtime(true) - $accountStart) * 1000);\n if ($accountMs > 1000) {\n $crmId = $companyData['id'] ?? $companyData['properties']['hs_object_id'] ?? 'unknown';\n $slowAccounts[] = ['crmId' => $crmId, 'ms' => $accountMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importAccountBatch timing', [\n 'teamId' => $this->team->getId(),\n 'account_count' => \\count($allCompanies),\n 'requested_count' => \\count($crmIds),\n 'not_found_count' => \\count($notFoundIds),\n 'total_ms' => $totalMs,\n 'fetch_api_ms' => $fetchMs,\n 'accounts_loop_ms' => $loopMs,\n 'avg_account_ms' => ! empty($allCompanies) ? (int) round($loopMs / \\count($allCompanies)) : 0,\n 'slow_accounts_count' => \\count($slowAccounts),\n 'slow_accounts' => array_slice($slowAccounts, 0, 10),\n ]);\n\n return $result;\n }\n\n private function getCompanyFields(): array\n {\n return [\n 'country',\n 'name',\n 'phone',\n 'domain',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'hs_object_id',\n 'createdate',\n 'hs_lastmodifieddate',\n ];\n }\n\n private function importAccount($crmData): ?Account\n {\n $crmProviderId = $crmData['id'] ?? $crmData['properties']['hs_object_id'] ?? null;\n\n $this->logger->info('[HubSpot] importAccount', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n if (empty($crmData['properties'])) {\n $this->logger->info('[HubSpot] importAccount failed: empty properties', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return null;\n }\n\n $properties = $crmData['properties'];\n $crmId = (string) $properties['hs_object_id'];\n\n $countryCode = isset($properties['country']) ? $this->convertCountryNameToCode($properties['country']) : null;\n\n if (isset($properties['phone'])) {\n // Trim to our width and attempt to parse it.\n $number = mb_strimwidth($properties['phone'], 0, 25);\n $parsedNumber = parsePhoneNumber($countryCode, $number);\n } else {\n $parsedNumber = [];\n }\n\n $name = '[unknown]';\n if (isset($properties['name'])) {\n $name = $properties['name'];\n }\n\n $photoPath = $this->prospectPhotoPathService->getOrGeneratePhotoPath(\n $this->config,\n $crmId,\n Account::class,\n $crmId,\n $name\n );\n\n $industry = null;\n if (isset($properties['industry'])) {\n $industry = mb_strimwidth($properties['industry'], 0, 40);\n }\n\n $ownerId = $profile = null;\n if (isset($properties['hubspot_owner_id'])) {\n $ownerId = $properties['hubspot_owner_id'];\n $profile = $this->crmEntityRepository->findProfileByExternalId($this->config, (string) $ownerId);\n }\n\n $domain = null;\n if (isset($properties['domain'])) {\n $domain = StringUtil::resolveDomain($properties['domain']);\n }\n\n $remotelyCreatedAt = null;\n if (isset($properties['createdate']) && ! empty($properties['createdate'])) {\n $remotelyCreatedAt = Carbon::parse($properties['createdate']);\n }\n\n $data = [\n 'crm_provider_id' => $crmId,\n 'team_id' => $this->team->id,\n 'user_id' => $profile ? $profile->user_id : null,\n 'owner_id' => $ownerId,\n 'name' => mb_strimwidth($name, 0, 191),\n 'photo_path' => $photoPath,\n 'industry' => $industry,\n 'domain' => $domain !== null\n ? substr($domain, 0, 191)\n : null,\n 'phone' => $parsedNumber['phone'] ?? null,\n 'ext' => $parsedNumber['ext'] ?? null,\n 'country_code' => $countryCode,\n 'remotely_created_at' => $remotelyCreatedAt,\n ];\n\n return $this->crmEntityRepository->importAccount($this->config, $data);\n }\n\n public function deleteContact(string $crmProviderId): bool\n {\n try {\n $contact = $this->crmEntityRepository->findContactByExternalId($this->config, $crmProviderId);\n\n if (! $contact) {\n $this->logger->info('[HubSpot] Contact not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $contact->getId();\n\n $this->logger->info('[HubSpot] Deleting contact via webhook', [\n 'contact_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $contact->delete();\n DeleteContactJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete contact via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n public function deleteAccount(string $crmProviderId): bool\n {\n try {\n $account = $this->crmEntityRepository->findAccountByExternalId($this->config, $crmProviderId);\n\n if (! $account) {\n $this->logger->info('[HubSpot] Account not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $account->getId();\n\n $this->logger->info('[HubSpot] Deleting account via webhook', [\n 'account_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $account->delete();\n DeleteAccountJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete account via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n public function deleteOpportunity(string $crmProviderId): bool\n {\n try {\n $opportunity = $this->crmEntityRepository->findOpportunityByExternalId($this->config, $crmProviderId);\n\n if (! $opportunity) {\n $this->logger->info('[HubSpot] Opportunity not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $opportunity->getId();\n\n $this->logger->info('[HubSpot] Deleting opportunity via webhook', [\n 'opportunity_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $opportunity->delete();\n DeleteOpportunityJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete opportunity via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Support\\Str;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteAccountJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteContactJob;\nuse Jiminny\\Jobs\\Crm\\Delete\\DeleteOpportunityJob;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Services\\Avatar\\ProspectPhotoPathService;\nuse Jiminny\\Services\\Crm\\Hubspot\\HubspotClientInterface;\nuse Jiminny\\Services\\Crm\\Hubspot\\WebhookSyncBatchProcessor;\nuse Jiminny\\Utils\\StringUtil;\n\ntrait SyncCrmEntitiesTrait\n{\n use OpportunitySyncTrait;\n private const string CDN_URL = 'https://cdn2.hubspot.net/';\n protected CrmEntityRepository $crmEntityRepository;\n protected ProspectPhotoPathService $prospectPhotoPathService;\n\n private function getAssociationDataForCollection(array $collection, string $fromObject, string $toObject): array\n {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $hsOpportunityIds = array_column($collection, 'id');\n\n return $this->client->getAssociationsData($hsOpportunityIds, $fromObject, $toObject);\n }\n\n private function importAssociationData(array $collection, array $associatedData): array\n {\n $data = [];\n if (! empty($associatedData[$collection['id']])) {\n foreach ($associatedData[$collection['id']] as $id) {\n $data[] = [\n 'id' => $id,\n ];\n }\n }\n\n return ['results' => $data];\n }\n\n /**\n * Sync contacts modified since a given date (manual sync mode).\n *\n * This method fetches contacts from HubSpot API based on modification date and\n * imports them one by one. It is used for:\n * - Manual sync commands (e.g., crm:sync-contact with --from parameter)\n * - Initial sync for new teams\n * - Backfill operations\n *\n * For regular sync webhook batchSyncContacts is used:\n *\n * @param Carbon $since Fetch contacts modified after this date\n * @param Carbon|null $to Optional end date for modification range\n *\n * @return int Number of contacts successfully synced\n */\n public function syncContacts(Carbon $since, ?Carbon $to = null): int\n {\n $syncCount = 0;\n\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getContactFields();\n $payload = $this->payloadBuilder->getRecentlyUpdatedSearchPayload($since, $to, $fields);\n\n foreach ($this->client->getPaginatedDataGenerator($payload, 'contacts') as $hsContact) {\n $this->importContact($hsContact);\n $syncCount++;\n }\n } catch (Exception $exception) {\n $this->logger->error('[' . $this->getDisplayName() . '] Sync contacts failed', [\n 'teamId' => $this->team->getUuid(),\n 'reason' => $exception->getMessage(),\n ]);\n }\n\n return $syncCount;\n }\n\n /**\n * @inheritdoc\n */\n public function syncContact(string $crmId): ?Contact\n {\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getContactFields();\n $hsContact = $this->client->getContactById($crmId, $fields);\n } catch (\\HubSpot\\Client\\Crm\\Contacts\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact fetch failed', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n } catch (CrmException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n if (empty($hsContact['properties']) || empty($hsContact['id'])) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Contact data incomplete', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'has_properties' => ! empty($hsContact['properties']),\n 'has_id' => ! empty($hsContact['id']),\n ]);\n\n return null;\n }\n\n return $this->importContact($hsContact);\n }\n\n private function getContactFields(): array\n {\n return [\n 'associatedcompanyid',\n 'country',\n 'firstname',\n 'lastname',\n 'phone',\n 'mobilephone',\n 'email',\n 'photo',\n 'hs_avatar_filemanager_key',\n 'jobtitle',\n 'hubspot_owner_id',\n 'hs_object_id',\n 'createdate',\n 'hs_lastmodifieddate',\n ];\n }\n\n /**\n * @inheritdoc\n */\n private function importContact($crmData, array $accountMappings = []): ?Contact\n {\n $crmProviderId = $crmData['id'] ?? null;\n\n $this->logger->info('[HubSpot] importContact', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n if (empty($crmData['properties'])) {\n $this->logger->info('[HubSpot] importContact failed: empty properties', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return null;\n }\n\n $properties = $crmData['properties'];\n $crmId = (string) $crmData['id'];\n\n $accountId = $this->resolveContactAccount($properties, $accountMappings);\n $data = $this->buildContactData($crmId, $properties, $accountId);\n\n return $this->crmEntityRepository->importContact($this->config, $data);\n }\n\n private function resolveContactAccount(array $properties, array $accountMappings): ?int\n {\n if (empty($properties['associatedcompanyid'])) {\n return null;\n }\n\n $companyId = (string) $properties['associatedcompanyid'];\n\n if (! empty($accountMappings)) {\n return $accountMappings[$companyId] ?? null;\n }\n\n return $this->crmEntityRepository->findAccountByExternalId(\n $this->team->getCrmConfiguration(),\n $companyId\n )?->getId() ?? $this->syncAccount($companyId)?->getId();\n }\n\n private function buildContactData(string $crmId, array $properties, ?int $accountId): array\n {\n $countryCode = $this->buildContactCountry($properties);\n $name = $this->buildContactName($properties);\n $photoPath = $this->teamService->generateAvatar(\n $crmId,\n empty($name) ? ($properties['email'] ?? 'N/A') : $name,\n );\n $parsedNumber = $this->buildContactPhone($countryCode, $properties);\n $mobileNumber = $this->buildContactMobilePhone($countryCode, $properties);\n\n $ownerId = $properties['hubspot_owner_id'] ?? null;\n $profile = $ownerId !== null\n ? $this->crmEntityRepository->findProfileByExternalId($this->config, (string) $ownerId)\n : null;\n\n $ext = (isset($parsedNumber['ext']) && is_string($parsedNumber['ext']) && strlen($parsedNumber['ext']) <= 10)\n ? $parsedNumber['ext']\n : null;\n\n $title = isset($properties['jobtitle']) ? mb_strimwidth($properties['jobtitle'], 0, 128) : null;\n $email = isset($properties['email']) ? mb_strimwidth($properties['email'], 0, 191) : null;\n $remotelyCreatedAt = ! empty($properties['createdate']) ? Carbon::parse($properties['createdate']) : null;\n\n return [\n 'crm_provider_id' => $crmId,\n 'team_id' => $this->team->getId(),\n 'account_id' => $accountId,\n 'user_id' => $profile?->getUserId(),\n 'owner_id' => $ownerId,\n 'name' => $name,\n 'title' => $title,\n 'email' => $email,\n 'country_code' => $countryCode,\n 'phone' => $parsedNumber['phone'] ?? null,\n 'mobile_phone' => $mobileNumber ?? null,\n 'ext' => $ext,\n 'photo_path' => $photoPath,\n 'remotely_created_at' => $remotelyCreatedAt,\n ];\n }\n\n /**\n * @param $properties\n */\n private function buildContactName($properties): string\n {\n if (is_array($properties)) {\n return $this->buildContactNameFromArray($properties);\n }\n\n return $this->buildContactNameFromObject($properties);\n }\n\n private function buildContactNameFromArray(array $properties): string\n {\n if (! empty($properties['name'])) {\n return mb_strimwidth($properties['name'], 0, 100);\n }\n\n $name = '';\n if (! empty($properties['firstname'])) {\n $name = $properties['firstname'] . ' ';\n }\n\n if (! empty($properties['lastname'])) {\n $name .= $properties['lastname'];\n }\n\n if ($name === '' && ! empty($properties['email'])) {\n $name = $properties['email'];\n }\n\n return mb_strimwidth($name, 0, 100);\n }\n\n private function buildContactNameFromObject($properties): string\n {\n $name = '';\n if (isset($properties->firstname)) {\n $name = $properties->firstname->value . ' ';\n }\n if (isset($properties->lastname)) {\n $name .= $properties->lastname->value;\n }\n if ($name === '' && isset($properties->email)) {\n $name = $properties->email->value;\n }\n\n return mb_strimwidth($name, 0, 100);\n }\n\n /**\n * @param $properties\n */\n private function buildContactPhone(?string $countryCode, $properties): ?array\n {\n if (is_array($properties) && empty($properties['phone']) === false) {\n $number = mb_strimwidth($properties['phone'], 0, 25);\n\n return parsePhoneNumber($countryCode, $number);\n } elseif (isset($properties->phone)) {\n $number = mb_strimwidth($properties->phone->value, 0, 25);\n\n return parsePhoneNumber($countryCode, $number);\n }\n\n return [];\n }\n\n /**\n * @param $properties\n */\n private function buildContactMobilePhone(?string $countryCode, $properties): ?string\n {\n return isset($properties['mobilephone'])\n ? Str::limit(phone_e164($countryCode, $properties['mobilephone']), 25, '')\n : null;\n }\n\n /**\n * @param $properties\n * @param $account\n */\n private function buildContactCountry($properties): ?string\n {\n if (is_array($properties) && empty($properties['country']) === false) {\n return $this->convertCountryNameToCode($properties['country']);\n }\n\n if (isset($properties->country)) {\n return $this->convertCountryNameToCode($properties->country->value);\n }\n\n return null;\n }\n\n /**\n * HubSpot doesn't have leads, so this method does nothing.\n *\n * @param Carbon $since\n * @param Carbon|null $to\n * @param string|null $crmProfileId\n *\n * @return int\n */\n public function syncLeads(Carbon $since, ?Carbon $to = null, ?string $crmProfileId = null): int\n {\n // Mark unused parameters to avoid code smell warnings\n unset($since, $to, $crmProfileId);\n\n return 0;\n }\n\n /**\n * HubSpot doesn't have leads.\n *\n * @param string $crmId\n *\n * @inheritdoc\n */\n public function syncLead(string $crmId): ?Lead\n {\n // Mark unused parameter to avoid code smell warnings\n unset($crmId);\n\n return null;\n }\n\n /**\n * Sync accounts (companies) modified since a given date (manual sync mode).\n *\n * This method fetches companies from HubSpot API based on modification date and\n * imports them one by one. It is used for:\n * - Manual sync commands (e.g., crm:sync-account with --from parameter)\n * - Initial sync for new teams\n * - Backfill operations\n *\n * For regular sync webhook batchSyncCompanies is used:\n *\n * @param Carbon $since Fetch companies modified after this date\n * @param Carbon|null $to Optional end date for modification range\n *\n * @return int Number of companies successfully synced\n */\n public function syncAccounts(Carbon $since, ?Carbon $to = null): int\n {\n $syncCount = 0;\n\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getCompanyFields();\n $payload = $this->payloadBuilder->getRecentlyUpdatedSearchPayload($since, $to, $fields);\n\n foreach ($this->client->getPaginatedDataGenerator($payload, 'companies') as $hsAccount) {\n $this->importAccount($hsAccount);\n $syncCount++;\n }\n } catch (Exception $exception) {\n $this->logger->error('[' . $this->getDisplayName() . '] Sync accounts failed', [\n 'teamId' => $this->team->getUuid(),\n 'reason' => $exception->getMessage(),\n ]);\n }\n\n return $syncCount;\n }\n\n /**\n * @inheritdoc\n */\n public function syncAccount(string $crmId): ?Account\n {\n try {\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $fields = $this->getCompanyFields();\n $hsAccount = $this->client->getAccountById($crmId, $fields);\n } catch (\\HubSpot\\Client\\Crm\\Companies\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Account fetch failed', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n } catch (CrmException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Account not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n return $this->importAccount($hsAccount);\n }\n\n /**\n * Process webhook-collected contact batches.\n *\n * Drains Redis sets containing contact CRM IDs collected from webhook events\n * and dispatches ImportContactBatch jobs for batch processing.\n *\n * @return int Number of contact IDs dispatched to jobs\n */\n public function batchSyncContacts(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_CONTACT,\n $configId\n );\n }\n\n public function importContactBatchByIds(array $crmIds): array\n {\n $result = [\n 'success_count' => 0,\n 'failed_ids' => [],\n 'errors' => [],\n ];\n\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $batchStart = microtime(true);\n $slowContacts = [];\n\n $fetchStart = microtime(true);\n $allContacts = $this->fetchContactsByIdsInChunks($crmIds);\n $fetchMs = (int) round((microtime(true) - $fetchStart) * 1000);\n\n $fetchedIds = array_map('strval', array_column($allContacts, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact CRM IDs not found in HubSpot', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allContacts),\n ]);\n }\n\n if (empty($allContacts)) {\n return $result;\n }\n\n $prepareStart = microtime(true);\n $accountMappings = $this->prepareAccountMappingsForContacts($allContacts);\n $prepareAccountsMs = (int) round((microtime(true) - $prepareStart) * 1000);\n\n $loopStart = microtime(true);\n foreach ($allContacts as $contactData) {\n $contactStart = microtime(true);\n\n try {\n $contact = $this->importContact($contactData, $accountMappings);\n if ($contact !== null) {\n $result['success_count']++;\n }\n } catch (\\Throwable $e) {\n $crmId = $contactData['id'] ?? 'unknown';\n $result['failed_ids'][] = $crmId;\n $result['errors'][$crmId] = $e->getMessage();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import contact', [\n 'teamId' => $this->team->getId(),\n 'crmId' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n }\n\n $contactMs = (int) round((microtime(true) - $contactStart) * 1000);\n if ($contactMs > 1000) {\n $slowContacts[] = ['crmId' => $contactData['id'] ?? 'unknown', 'ms' => $contactMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importContactBatch timing', [\n 'teamId' => $this->team->getId(),\n 'contact_count' => \\count($allContacts),\n 'requested_count' => \\count($crmIds),\n 'not_found_count' => \\count($notFoundIds),\n 'total_ms' => $totalMs,\n 'fetch_api_ms' => $fetchMs,\n 'prepare_accounts_ms' => $prepareAccountsMs,\n 'contacts_loop_ms' => $loopMs,\n 'avg_contact_ms' => ! empty($allContacts) ? (int) round($loopMs / \\count($allContacts)) : 0,\n 'slow_contacts_count' => \\count($slowContacts),\n 'slow_contacts' => array_slice($slowContacts, 0, 10),\n ]);\n\n return $result;\n }\n\n private function fetchContactsByIdsInChunks(array $crmIds): array\n {\n $fields = $this->getContactFields();\n $allContacts = [];\n\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n try {\n $contacts = $this->client->getContactsByIds($chunk, $fields);\n foreach ($contacts as $contactData) {\n $allContacts[] = $contactData;\n }\n } catch (\\Throwable $e) {\n // @TODO what will happen if this exception is thrown\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch contact fetch failed', [\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n\n return $allContacts;\n }\n\n private function prepareAccountMappingsForContacts(array $contacts): array\n {\n $companyIds = [];\n foreach ($contacts as $contact) {\n $companyId = $contact['properties']['associatedcompanyid'] ?? null;\n if ($companyId !== null && $companyId !== '') {\n $companyIds[] = (string) $companyId;\n }\n }\n\n $companyIds = array_unique($companyIds);\n\n if (empty($companyIds)) {\n return [];\n }\n\n $mappings = $this->crmEntityRepository\n ->getExistingAccountIdsMap($this->config, $companyIds);\n\n $missingCompanyIds = array_diff($companyIds, array_keys($mappings));\n\n if (empty($missingCompanyIds)) {\n return $mappings;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing accounts for contacts', [\n 'teamId' => $this->team->getId(),\n 'total_companies' => \\count($companyIds),\n 'existing_companies' => \\count($mappings),\n 'missing_companies' => \\count($missingCompanyIds),\n ]);\n\n try {\n $syncedAccounts = $this->batchSyncAccountsForContacts($missingCompanyIds);\n $mappings = array_merge($mappings, $syncedAccounts);\n } catch (\\Throwable $e) {\n $this->logger->error('[' . $this->getDisplayName() . '] Failed to batch sync missing accounts', [\n 'teamId' => $this->team->getId(),\n 'missingCompanyIds' => $missingCompanyIds,\n 'missingCount' => count($missingCompanyIds),\n 'error' => $e->getMessage(),\n ]);\n }\n\n return $mappings;\n }\n\n private function batchSyncAccountsForContacts(array $companyIds): array\n {\n $syncedAccounts = [];\n $fields = $this->getCompanyFields();\n\n foreach (array_chunk($companyIds, self::BATCH_SIZE) as $chunk) {\n try {\n $companies = $this->client->getCompaniesByIds($chunk, $fields);\n\n foreach ($companies as $companyData) {\n try {\n $account = $this->importAccount($companyData);\n if ($account) {\n $syncedAccounts[$account->getCrmProviderId()] = $account->getId();\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import account in batch', [\n 'teamId' => $this->team->getId(),\n 'companyId' => $companyData['id'] ?? 'unknown',\n 'error' => $e->getMessage(),\n ]);\n }\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch company fetch failed', [\n 'teamId' => $this->team->getId(),\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n return $syncedAccounts;\n }\n\n /**\n * Process webhook-collected company batches.\n *\n * Drains Redis sets containing company CRM IDs collected from webhook events\n * and dispatches ImportAccountBatch jobs for batch processing.\n *\n * @return int Number of company IDs dispatched to jobs\n */\n public function batchSyncCompanies(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_COMPANY,\n $configId\n );\n }\n\n public function importAccountBatchByIds(array $crmIds): array\n {\n $result = [\n 'success_count' => 0,\n 'failed_ids' => [],\n 'errors' => [],\n ];\n\n if (! $this->client instanceof HubspotClientInterface) {\n throw new \\InvalidArgumentException('Client must implement HubspotClientInterface');\n }\n\n $batchStart = microtime(true);\n $slowAccounts = [];\n\n $fields = $this->getCompanyFields();\n $allCompanies = [];\n\n $fetchStart = microtime(true);\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n try {\n $companies = $this->client->getCompaniesByIds($chunk, $fields);\n foreach ($companies as $companyData) {\n $allCompanies[] = $companyData;\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch company fetch failed', [\n 'chunk_size' => \\count($chunk),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n }\n $fetchMs = (int) round((microtime(true) - $fetchStart) * 1000);\n\n $fetchedIds = array_map('strval', array_column($allCompanies, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Company CRM IDs not found in HubSpot', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allCompanies),\n ]);\n }\n\n $loopStart = microtime(true);\n foreach ($allCompanies as $companyData) {\n $accountStart = microtime(true);\n\n try {\n $account = $this->importAccount($companyData);\n if ($account !== null) {\n $result['success_count']++;\n }\n } catch (\\Throwable $e) {\n $crmId = $companyData['id'] ?? $companyData['properties']['hs_object_id'] ?? 'unknown';\n $result['failed_ids'][] = $crmId;\n $result['errors'][$crmId] = $e->getMessage();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import account', [\n 'crmId' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n }\n\n $accountMs = (int) round((microtime(true) - $accountStart) * 1000);\n if ($accountMs > 1000) {\n $crmId = $companyData['id'] ?? $companyData['properties']['hs_object_id'] ?? 'unknown';\n $slowAccounts[] = ['crmId' => $crmId, 'ms' => $accountMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importAccountBatch timing', [\n 'teamId' => $this->team->getId(),\n 'account_count' => \\count($allCompanies),\n 'requested_count' => \\count($crmIds),\n 'not_found_count' => \\count($notFoundIds),\n 'total_ms' => $totalMs,\n 'fetch_api_ms' => $fetchMs,\n 'accounts_loop_ms' => $loopMs,\n 'avg_account_ms' => ! empty($allCompanies) ? (int) round($loopMs / \\count($allCompanies)) : 0,\n 'slow_accounts_count' => \\count($slowAccounts),\n 'slow_accounts' => array_slice($slowAccounts, 0, 10),\n ]);\n\n return $result;\n }\n\n private function getCompanyFields(): array\n {\n return [\n 'country',\n 'name',\n 'phone',\n 'domain',\n 'hs_avatar_filemanager_key',\n 'industry',\n 'hubspot_owner_id',\n 'hs_object_id',\n 'createdate',\n 'hs_lastmodifieddate',\n ];\n }\n\n private function importAccount($crmData): ?Account\n {\n $crmProviderId = $crmData['id'] ?? $crmData['properties']['hs_object_id'] ?? null;\n\n $this->logger->info('[HubSpot] importAccount', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n if (empty($crmData['properties'])) {\n $this->logger->info('[HubSpot] importAccount failed: empty properties', [\n 'crm_provider_id' => $crmProviderId,\n 'config_id' => $this->config->getId(),\n ]);\n\n return null;\n }\n\n $properties = $crmData['properties'];\n $crmId = (string) $properties['hs_object_id'];\n\n $countryCode = isset($properties['country']) ? $this->convertCountryNameToCode($properties['country']) : null;\n\n if (isset($properties['phone'])) {\n // Trim to our width and attempt to parse it.\n $number = mb_strimwidth($properties['phone'], 0, 25);\n $parsedNumber = parsePhoneNumber($countryCode, $number);\n } else {\n $parsedNumber = [];\n }\n\n $name = '[unknown]';\n if (isset($properties['name'])) {\n $name = $properties['name'];\n }\n\n $photoPath = $this->prospectPhotoPathService->getOrGeneratePhotoPath(\n $this->config,\n $crmId,\n Account::class,\n $crmId,\n $name\n );\n\n $industry = null;\n if (isset($properties['industry'])) {\n $industry = mb_strimwidth($properties['industry'], 0, 40);\n }\n\n $ownerId = $profile = null;\n if (isset($properties['hubspot_owner_id'])) {\n $ownerId = $properties['hubspot_owner_id'];\n $profile = $this->crmEntityRepository->findProfileByExternalId($this->config, (string) $ownerId);\n }\n\n $domain = null;\n if (isset($properties['domain'])) {\n $domain = StringUtil::resolveDomain($properties['domain']);\n }\n\n $remotelyCreatedAt = null;\n if (isset($properties['createdate']) && ! empty($properties['createdate'])) {\n $remotelyCreatedAt = Carbon::parse($properties['createdate']);\n }\n\n $data = [\n 'crm_provider_id' => $crmId,\n 'team_id' => $this->team->id,\n 'user_id' => $profile ? $profile->user_id : null,\n 'owner_id' => $ownerId,\n 'name' => mb_strimwidth($name, 0, 191),\n 'photo_path' => $photoPath,\n 'industry' => $industry,\n 'domain' => $domain !== null\n ? substr($domain, 0, 191)\n : null,\n 'phone' => $parsedNumber['phone'] ?? null,\n 'ext' => $parsedNumber['ext'] ?? null,\n 'country_code' => $countryCode,\n 'remotely_created_at' => $remotelyCreatedAt,\n ];\n\n return $this->crmEntityRepository->importAccount($this->config, $data);\n }\n\n public function deleteContact(string $crmProviderId): bool\n {\n try {\n $contact = $this->crmEntityRepository->findContactByExternalId($this->config, $crmProviderId);\n\n if (! $contact) {\n $this->logger->info('[HubSpot] Contact not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $contact->getId();\n\n $this->logger->info('[HubSpot] Deleting contact via webhook', [\n 'contact_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $contact->delete();\n DeleteContactJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete contact via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n public function deleteAccount(string $crmProviderId): bool\n {\n try {\n $account = $this->crmEntityRepository->findAccountByExternalId($this->config, $crmProviderId);\n\n if (! $account) {\n $this->logger->info('[HubSpot] Account not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $account->getId();\n\n $this->logger->info('[HubSpot] Deleting account via webhook', [\n 'account_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $account->delete();\n DeleteAccountJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete account via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n public function deleteOpportunity(string $crmProviderId): bool\n {\n try {\n $opportunity = $this->crmEntityRepository->findOpportunityByExternalId($this->config, $crmProviderId);\n\n if (! $opportunity) {\n $this->logger->info('[HubSpot] Opportunity not found for deletion', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n // return success because we do not know which instance is the target\n return true;\n }\n\n $id = $opportunity->getId();\n\n $this->logger->info('[HubSpot] Deleting opportunity via webhook', [\n 'opportunity_id' => $id,\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n ]);\n\n $opportunity->delete();\n DeleteOpportunityJob::dispatch($id)->afterCommit();\n\n return true;\n } catch (Exception $e) {\n $this->logger->error('[HubSpot] Failed to delete opportunity via webhook', [\n 'crm_provider_id' => $crmProviderId,\n 'team_id' => $this->team->getId(),\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\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}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3641
|
134
|
14
|
2026-05-07T12:32:23.125753+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157143125_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
matc
Inherited members (⌘R)
Anonymous Classes (⌘I) matc
Inherited members (⌘R)
Anonymous Classes (⌘I)
Lambdas (⌘L)
SyncCrmEntitiesTrait.php...
|
[{"role":"AXTextField","text [{"role":"AXTextField","text":"matc","depth":1,"bounds":{"left":0.5212766,"top":0.31444532,"width":0.030917553,"height":0.022346368},"on_screen":true,"value":"matc","role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Inherited members (⌘R)","depth":1,"bounds":{"left":0.5242686,"top":0.33998403,"width":0.052526597,"height":0.022346368},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Anonymous Classes (⌘I)","depth":1,"bounds":{"left":0.58011967,"top":0.33998403,"width":0.052526597,"height":0.022346368},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Lambdas (⌘L)","depth":1,"bounds":{"left":0.6359708,"top":0.33998403,"width":0.052526597,"height":0.022346368},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"SyncCrmEntitiesTrait.php","depth":1,"bounds":{"left":0.5242686,"top":0.31364724,"width":0.19980054,"height":0.026336791},"on_screen":true,"role_description":"text"}]...
|
-9148788009616122181
|
7532062033701913281
|
visual_change
|
hybrid
|
NULL
|
matc
Inherited members (⌘R)
Anonymous Classes (⌘I) matc
Inherited members (⌘R)
Anonymous Classes (⌘I)
Lambdas (⌘L)
SyncCrmEntitiesTrait.php
PhostormINavigarecodeFV faVsco.js© SyncToUserPilot.phpC) RateLimitAwareWrapper.pnp• M CalendarC) AddRateLimitCommana.pnpT IntegrationApp/.../SyncCrmEntitiesTrait.php© SyncOpportunity.php> • Conference© webnooksyncbatchProcessor.pngv D Crm> M BullhornTImportBatchJobTrait.phg(©) Middleware/RateLimited.pnpHip/RateLimited.phg)BaserateLimiter.phpC service.phg> D Close> @ Copper> @ CrmObjects@ Hubspot/../SyncCrmEntitiesTrait.php xtrait synccrmentitzestrait> O DecorateActivity> C DummyU helpersv U HuDSpOta AccountsyncstrateayActions• ContacisyncstrareavD DTO0 Fields71 6tu JournaD Metadatev OpportunitvSvncStratea Concerns© HubspotLastModifi€ 100 @, Gt© HubspotLastModifieC) HubsnotLastModitie(C) HubsnotLastModifie(C) HubspotLastModifie(C) HubsnotSinaleSvncc, HuhsnotSvneStrate(C) HubsnotWehhookR> M PadinationD ProspectSearchStratecD RedisD ServiceTraitsu opportunitysyncire 11dV synccrmenutes tra 113© SyncFields Trait.php 114( WriteCrmTrait.php>O Utils.0 Webhook|c) BatchSvncCollector.phC) BatchSvncRedisServicC) Closed Dea StadesServC)DecorateActivitv.ohoC) FieldTivoeConverter.oh© HubspotClientinterfaceC) HubsootTokenManade© PayloadBuilder.php(C) RemoteCrm@biectManga ResnonceNormalize nh* - Backfill operations* ror regular sync webnook bacchsyncconcacts is used.* doaram carbon sSince reuch concacus moulrled arcer chis date: Qparam CarbonInulz Sto Optional end date for modification rangepublic function svncContacts(Carbon Ssince. ?Carbon Sto = null): int{...}* Ginheritdodnublic function svncContact(strina Scrmid: ?Contacttryif ( Sthis->client instanceof HubspotClientInterface) i+hoow new TnvalidAraumentSycentiond medage: 'Client must implement HubspotClientInterface'):Sfields= Sthis->aettontactFioldco•$hsContact = Sthis->client->getContactById($crmId, $fields):} catch (\HubSpot\Client\Crm\Contacts \ApiException $e) {Cthic-nloanon.sinfortrt• Sthis->getDisplayName . '] Contact fetch failed', ['teamId' => $this->team->getUuid."crmld => scrmld,'reason' => $e->qetMessageO1);} catch (CrmException Se) {Sthis->logger->info@f'.Sthis->qetd1splavNameo.'] Contact not found'.["teamid => sthus->team->cetuuido"reason' => Se->aetMessageOl14iemntv(ChstontactiinronentieciilemntvShccontactftid11.ngSthis-sloagen-swanningftrt Sthis-aethicnlavNameo"Contact data incomnlete!.teamtd' => Sthis->team->aetlluidoarQube 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)• Lukas sterka 121 • In 1h o0mInu / May 10.32-20AskJiminnyReportActivityServiceTest -= custom.log« SF [jiminny@localhost]HS_local (jiminny@localhost]« console [PROD]console [STAGINGIQ- Hubspot22R Match case[2026-05-07 12:28:14] local.INF0: Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities" "memoryBeforeCommandInMb":62.0, "memo "[2026-05-07 12:28:17] local.INF0:[SocialAccountServicel Fetching token {"socialAccountId":1499 "provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344"|2020-05-01 12.20.1/ Local.LNrU:ISOCHALACCOUnLSENVACeILOKENNeEusNeTesinoEtSOctaLACCOUncLoN147FONOVLden nUDSDосизвсом мешатоюномн45555174-0545-40488осУа-C4OCOВ[2026-05-07 12:28:17] local.INF0:[EncryptedTokenManager] Generating access token. {"mode": "legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344" , "trace_id" : "5ea79т 462 X32 ^ V (2026-05-07 12:28:171 Local.INFO: [SocialAccountServicell Refreshing token from provider "socialAccountId":1499, "provider" : "hubspot", "nefreshToken": "96f94c623a404e02ebdbf07f1b[2026-05-07 12:28:18] Local.NOTICE: Monitoring start{"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5", "trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}12026-05-082828818OcaL-NOCEH MOn tONng endcorreLation 1casnaa0b/0-0006-448а-b0cc-asc245b4aebsn"trace омяОВеруе5-8404-410-90на-а8о4свен5 тн2[2026-05-07 12•28:181 local. INF0:f"correlation id"."273355f2-6315-4b20-bc9a-c26c681d6344" "trace id"."5ea79a26-c838-48e8-9913-93ad508146- [2026-05-07 12:28:18] Local.INF0:SocialAccountloserver Access token was modhrled, encrvotino"correlation 1d":[CREDIT_CARD]-0c9a-026068106544""trace 1d":"Sea72a26:[2026-05-07 12:28:18] Local. INFO:[SocialAccountService] Token refreshed {"socialAccountId":1499, "provider": "hubspot", "state": "connected"} {"correlation_id":"273355f2-6315-4b22026-05-07 12:28:18 Local.INF0:IcomownerReso ver Dntemnatiion owner matched as CRM ownenweem onoviden nhubspotlcom ownen rZ8,team WaWconnellataionSGWA 206615512[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564", "reason":"[429] Client error: 'GET https://api.hubapi.com/crm/v3/objects/deals/37Q matcSvncermEntitiesTrait.phong limit.", "errorType)":"RATE_LIMIT\", "correlationid" (truncated...)9a26-c838-48e8-9913-93ad508146a6",Inherited members J3RAnonymous Classes (28))Lambdas (&L)pi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Cct.","errorType":"RATE_LIMIT","correlationid" (truncated...)): [429] Client error:'GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_obing limit.","errorType\":"RATE_LIMIT\",\"correlationId" (truncated...)hp:704)p(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_idCrm\\Deals\\Api\ \BasicApi->getById('374720564', 'hs_object_id,de...',companzes, conta....php (130): Jiminny\(Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)Services\Crm\Hubspotl|Service->syncOpportunity('374720564')Consolel\CommandsJiminnyDebugCommand->rateLimitood.php(56: Jiminny ConsoleCommandsJiminnyDebuqcommand->handle Ubnect Jiminny Jobs Jobbispat43): Illuminate\Container\BoundMethod::Illuminate|Container{closure'od.php(96): Illuminate\Container\Util::unwrapIfClosure(Obiect(Closure))od.php(35): Illuminate\Container\BoundMethod::callBoundMethod(Obiect(Illuminate\Foundation\Appl.onow99:Luminate Contarner Boundmethod::cauubnect euuuminate FoundationAno ucation). Anp(211): Illuminate\\Container\\Container->call(Array)eConsole Command->execute(Obiect SvmfonyComponent ConsoleInout Aravinout). Obfect onluminap(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\InpuConsole Command->run Obiect Sumfony Comoonent Console inout Aravinout), Obiect Sumfony Compononent\(Console\\Application->doRunCommand(Object(Jiminny\\Console\\Commands\\JiminnyDebugCommand),onentConsoleAppuication->doRunObiect Sumfony Comoonent Consolenout Aravinout). Obiect(Sv#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony|\Component|\Console\=#17/home/Ltiminny//vendor//apavelLfcamewook/scc/Tluminate/Eoundation/AnnLication..nhn(1235)._Mlluminatel\Eoundationl\Consolel|Kernel->handle(0hiect(SvmfonvlComnonentlfonsolel- #18 /home/iiminnv/antisan(13)• Tlluminatel|Foundation| \AnnLication-shandleCommand(0biect(Svmfonv||Comnonent||Console||Tnnut|\AravTnnut))l#10 <main?"3 {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344"', "trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}-12026-05-07 12-28:201 1ocalLTNE0• liminnv|ConsolelCommandslCommand..nun_Memoav_usage_hefone_stanting_command_{"command". "mailhoxeskin-listsanefnesh" "memonvRefoneßommandTnMh"[2026-05-07 12:28:20] local.INF0: Jiminny Console \Commands \Command::run Memory usage for command {"command": "mailbox:skip-lists:refresh", "memoryBeforeCommandInMb" :62.0, "memorSAEÍNA CAMMANd EWCAmMAnduClmAtllhAyChAtCheneAcocel lmemoayRefoeodommandiMЬШa10 n[2026-05-07 12:28:24] local.INFO:[EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8" "trace_id":"67798138— [2026-05-07 12:28:24] local.INF0:[EmailSchedule] FINISHED batch process {"host":"docker lamp 1" "processed":0} {"correlation id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8" "trace— [2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage for command {"command" : "mailbox:batch: process" "memoryBeforeCommandInMb" : 62.0, "memorvAfter[2026-05-07 12:28:27] local.INF0: Jiminny|Console\Commands\Command::run Memory usage before starting command {"command":"conference: moniton:count", "memoryBeforeCommandInMb" : 62[2026-05-07 12:28:27] local.INF0: Running conference:moniton:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"conrelation id":"a4e5e18f-9f8c-4196-[2026-05-07 12:28:27] local.INF0: [conference:moniton:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:001 {"conrelation id":"a4e5e18f-9f8c-4196-ace0-bf66W Windsurf Teamsio 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3640
|
134
|
13
|
2026-05-07T12:32:19.446144+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157139446_m2.jpg...
|
PhpStorm
|
faVsco.js – OpportunitySyncTrait.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All...
|
[{"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"width":0.008643617,"height":0.01915403},"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-1417133128833688403
|
-8348467362278560832
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
PhostormINavigarecodeKeractorFV faVsco.js?9 master k© SyncToUserPilot.phpC) RateLimitAwareWrapper.pnp> O Calendar> • ConferenceD Crm> M BullhornC) AddRateLimitCommand.pnpIntegratilonApp/./synecrmcnates tral.ong© webnooksyncbatchprocessor.pngTImportBatchJobTrait.php() Middleware/RateLimited.pnpHip/RateLimited.phg© BaseRateLimiter.php© Service.phpD Close> @ Copper> @ CrmObjects> O DecorateActivity> C DummyC Helpers( Hubspot/.../SyncCrmEntitiesTrait.phptralt Upportun1tysynciralt103v U HuDSpOt106a AccountsyncstrateayActions• Contacisyncstrareav109D DTO0 Fieldsu JournaD Metadatev OpportunitvSvncStrateM ConcernsC) Huosoot LastModitie© HubspotLastModifie128 đC) HubsnotLastModifie© HubspotLastModifie(C) HubsnotLastModifie@ HubspotSingleSyncc, HuhsnotSvneStrate© HubspotWebhookB> M PadinationD ProspectSearchStratecD RedisD ServiceTraitsOpportunitysyncireu synccrmcntuestrait.on© SyncFieldsTrait.php© WriteCrmTrait.php>O Utils.0 Webhook|© BatchSvncCollector.phC) BatchSvncRedisServicC) Closed Dea StadesServDealFieldsService.phpC)DecorateActivitv.ohoC) FieldivoeConverter.ohHubspotClientinterfaceC) HubsootTokenManade© PayloadBuilder.php(C) RemoteCrm@biectMang ResnonceNormalize nhpublic function syncupportunities(array Sparameters, ?string sstrategy = nuLu): 1nt- prepor teurolat,'last_synced_id' => $lastSyncedid,"dunation msl => SdurationMslneturn SrenontedTotal.private function handleSyncException(\Throwable $e, array $parameters): void{...}* dinherzzdocpubLic tunction syncupportunity string scrmid: ?Upportunlty$this->client->getQpportunityById($crmId, ['hs_object_id', 'dealname']);Sstrateay = $this->opportunitvSvncStrategvResolver->resolve(strateay: OpportunitvSvncStrateavResolver::STNGLE SYNC OPPORTUNTTY STRATEGY.ISparameters =1= Sthis->confi.a.erm id' => SermId.tryfif (! $strategy instanceof HubspotSingleSyncStrategy) ‹throw new InvalidArgumentException( message: 'Strategy must by HubspotSingleSyncStrategy');$hsOpportunity = $strategy->fetchOpportunity($parameters):} catch (\HubSpot \Client\Crm\Deals\ApiException $e) {Sthis->logger->info('[' . $this->getDisplayName@'] Opportunity not found'. ['teamld = sch1s->ceam->qecuu100."crmid => scrmld'reason' => $e->qetMessage@return null:arAube for IDE suanestionsa Detect more seawritvlssues lin vour D.Dffiles lltn SonarAube Claud for free //lDownload SonarOmbe Server /llllear more /llDonit ask adain /itodav 105251$ Lukas/Stefka 121 - in 1h 58 mThu 7 May 15:32:19AskJiminnyReportActivityServiceTest= custom.log« SF [jiminny@localhost]A HS_local [jiminny@localhost]« console [PROD]& console [STAGINGI22R Match case[2026-05-07 12:28:14] local.INF0:Jiminny\Console\Commands\Command::run Memory usage for command {"command":"dialers:monitor-activities" "memoryBeforeCommandInMb" :62.0, "memo a[2026-05-07 12:28:17] local.INF0:[SocialAccountServicel Fetching token {"socialAccountId":1499 "provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344"|2020-05-01 12.20.1/ Local.LNrU:SOCLaLACCOUnLseNveceloKenneeus etiesinnoEuSOctaLACCOUncLONe 47rOnOVedеnн nUDsро сизз всом нешатоютоми4655514-0545-40407осма-сOCOВ[2026-05-07 12:28:17] local.INF0:[EncryptedTokenManager] Generating access token. {"mode": "legacy"} {"correlation_id": "273355f2-6315-4b20-bc9a-c26c681d6344", "trace_id" : "5ea7941433 X2 M23 ^ Y [2026-05-07 12:28:171 1ocal.INF0: SocialAccountServicell Refreshing token from provider ("socialAccountId":1499, "provider":"hubspot", "refneshToken" : "96f94c623a404e02ebdbf07f1b[2026-05-07 12:28:18] local.NOTICE: Monitoring start{"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5" "trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}12026-05-082828818OcaL-NOCEH MOn tONng endcorreLation 1casnaa0b/0-0006-448а-b0cc-asc245b4aebsn"trace омяОВеруе5-8404-410-90на-а8о4свен5 тн2[2026-05-07 12•28:181 local, INF0:[SocialAccountObserverl Saving model {"correlation id"."273355f2-6315-4b20-bc9a-c26c681d6344" "trace id". "Sea79a26-c838-48e8-9913-93ad5081462026-05-07 12:28:18 Local.INF0:[2026-05-07 12:28:181 local. INF0:SocialAccountloserver Access token was modhrled, encrvotino"correlation 1d": [CREDIT_CARD]-0c9a-026068106544""trace 1d":"Sea/2a26.[SocialAccountService] Token refreshed {"socialAccountId":1499, "provider": "hubspot", "state": "connected"} {"correlation_id":"273355f2-6315-4b22026-05-07 12:28:18 Local.INF0:comownerReso ver Dntednattion owner matched as CRM ownenwcem orovader hubspotucom ownen r28.team a Wconnellatiion ШR 206k15512_ [2026-05-07 12:28:19] Local. INFO:[Hubspot] Failed to fetch opportunity {"crm_id":"374720564", "reason":"[429] Client error: 'GET https://api.hubapi.com/crm/v3/objects/deals/37i\"status\": "error)", "message\":\"You have reached your ten_secondly_rolling limit.", "errorType\":\"RATE_LIMIT\", "correlationid)" (truncated...)- "} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344", "trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}2026-05-01 12-28-10 1 ocalERROR: 420 Mtient erron.GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Cc{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationid" (truncated...){"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error:'GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_obj{\"status\":\"error\", \"message)":\"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT\",\"correlationId" (truncated...)at/home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)[stacktrace]- #0/home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot||Client|CrmDeals\Api BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\ \BasicApi->getById('374720564', 'hs_object_id,de...','companies, conta...')#2/home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/0pportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)= #3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny||Services||Crm|\Hubspot||Service->sync0pportunity(*374720564")_ #4 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(44): Jiminny|\Console\|Commands|\JiminnyDebugCommand->rateLimit()#5/home/iiminny/vendon/Lanavel/framework/src/Illuminate/Container/BoundMethod.php(36): Jiminny|Consolel|Commands|1JiminnyDebugCommand->handLe(0biect(JiminnylIJobsllJobDispat#6/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::Illuminate\Container{closurelO#7/home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\ContainerUtil::unwrapIfClosure(Obiect(Closure))#8 /home/jiminny/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminatel\Container\\BoundMethod::callBoundMethod(Object(Illuminate\\Foundation\\ApplomeWmIenoownaveWimameWoisoWnnAtenonWanenontneo1ow99onnatel NCOntaInEr a BOUNGMEtnOO HaCaaa tuoneca eaaumnate N ounda On vADo aca dOniA= #10 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.pho(211): Illuminatel(Container|\Container->cal1(Array)#11/home/jiminny/vendor/svmfonv/console/Coand//Command.oho (3410: TluminateConsoleCommand-›execute(Obiect SumfonyComponent ConsoleInout Aravinout). Obiect onlumina#12 /home/jiminny/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\\Component\\Console\\Command\\Command->run(Object(Symfony\\Component\\Console\\InpuFK 7home/E5iminny/vendon//symtonv/ consol le//Aoo 5 cation -oho GunvDR tu lumi nate uonso la ucommand»» nun cobr e ci es vmtonv comoonenta aconso le iunouta lAray nouta. obrtect esvm ionv Ncomoon- #14 /home/jiminny/vendor/symfony/console/Application.php(356): Symfony\\Component\\Console\\Application->doRunCommand(Object(Jiminny|\Console\\Commands\\JiminnyDebugCommand),—E:15 7home/E5m Inny/ Vendor//symtonv/ consol le//Aoo 5 cataion- 0ho €195)F Semtionv aTcomoonenta uconso le lVAoo ls catiion→>coRun Cbrtectz esvm ony ucomoonenta uconsol le lu noura lAcay nouan Omriectzesy#16 /home/jiminny/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\\Component\\Console\\Application->run(Object(Symfony|\Component|\Console\wwhome/E6m.Innw//Mendow/lanavelWEdoamewon.scc7atllmTattel/soundatalon//An0GTcataTonunh0/Gl/k1.9katbmElnatteEoundatalon.lonsolalkernehandleldlElecasvmonv/uTomnonentalionsolel= #18 /home/&iminnv/antisan(13)• Tlluminatel|Foundation| \Annlication-shandleCommand(0biect(Svmfonv|\Comnonent|\Console||Innut|\AravInnut))l#10 <main?"3 {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344"', "trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}12926-05-07 12-282201ncaLNENR Nm nny MonsdlAMmnandadommandacin Memoay lsane hefoce stastiing command command"-"maitlhoxaskin-listcanefinesh""memonvRefoceRommandiTnMh"r- [2026-05-07 12:28:20] local.INF0: Jiminny Console \Commands \Command::run Memory usage for command {"command": "mailbox:skip-lists:refresh", "memoryBeforeCommandInMb" :62.0, "memor12a24-05-07 12.29.241 1oc01 TNEO.r2a24-05-07 12.29.041 1oc01 TNE0•memAAVRAGAeACAmmAndTМЬШКО П[EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8"' "trace_id":"67798138imal Schedmlall STNTSHEn hatch neacnse fllhastl -"docken lamn 14 tnnaceecadl-0llconcollationAdH.1d101d5ch-1226-/A301-R0d/-d285d0d7,8h8" Itnace[2026-05-07 12:28:24] local.INF0: Jiminny|Console\Commands\Command::run Memory usage for command {"command": "mailbox:batch:process", "memonyBeforeCommandInMb":62.0, "memoryAfter[2026-05-07 12:28:27] local.INF0: Jiminny|Console\Commands\Command::run Memory usage before starting command {"command":"conference: moniton:count", "memoryBeforeCommandInMb" : 62→ [2026-05-07 12:28:27] local.INF0: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:001 {"correlation id":"a4e5e18f-9f8c-4196-[2026-05-07 12:28:27] local.INF0: [conference:monitor:count] No activities found in (2026-05-07 12:26:00. 2026-05-07 12:28:001|fisonnolotion ddll.1l0ho50106060,1104 ол0ALHSLWN Windsurf Teamio 4 spaces...
|
3638
|
NULL
|
NULL
|
NULL
|
|
3639
|
133
|
8
|
2026-05-07T12:32:19.547433+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157139547_m1.jpg...
|
PhpStorm
|
faVsco.js – Hubspot/…/SyncCrmEntitiesTrait.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
Search History
Hubspot
New Line...
|
[{"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":"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":"Hubspot","depth":4,"on_screen":true,"value":"Hubspot","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}]...
|
3003060951785363827
|
-8204349974642447424
|
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
Search History
Hubspot
New Line
iTerm2ShellEditViewSessionScriptsProfilesWindowHelp(wbl• Lukas/Stefka 121 - in 1h 58 m100%8DEV (docker)Thu 7 May 15:32:19181₴6DOCKERDEV (docker)H82worker-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: debugSyncing opportunity 0Syncing opportunity 25Syncing opportunity 50Syncing opportunity 75Syncingopportunity 100root@docker_lamp_1:/home/jiminny# php artisan jiminny:debugSyncing opportunity 0Syncing opportunity 25Syncing opportunity 50Syncing opportunity 75Syncing opportunity 100root@docker_lamp_1:/home/jiminny# php artisan jiminny:debugSyncing opportunity 0APP (-zsh)-zsh• 84|screenpipe*-zshDEVHubSpot\Client\Crm\Deals\ApiException[429] Client error: *GET [URL_WITH_CREDENTIALS] ]...
|
3637
|
NULL
|
NULL
|
NULL
|
|
3638
|
134
|
12
|
2026-05-07T12:32:13.766555+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157133766_m2.jpg...
|
PhpStorm
|
faVsco.js – OpportunitySyncTrait.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"AXCheckBox","text":"Search History","depth":3,"bounds":{"left":0.53457445,"top":0.07980846,"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":"Hubspot","depth":4,"bounds":{"left":0.5455452,"top":0.07980846,"width":0.11469415,"height":0.015961692},"on_screen":true,"value":"Hubspot","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.66921544,"top":0.07980846,"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":"AXButton","text":"Previous Occurrence","depth":4,"bounds":{"left":0.68484044,"top":0.07821229,"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":"Next Occurrence","depth":4,"bounds":{"left":0.69348407,"top":0.07821229,"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":"Search All","depth":4,"bounds":{"left":0.7044548,"top":0.07821229,"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":"Search Backward","depth":4,"bounds":{"left":0.7130984,"top":0.07821229,"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":"Search Forward","depth":4,"bounds":{"left":0.72174203,"top":0.07821229,"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":"Match сase","depth":4,"bounds":{"left":0.73038566,"top":0.07821229,"width":0.032247342,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"bounds":{"left":0.76263297,"top":0.07821229,"width":0.023271276,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"bounds":{"left":0.7859042,"top":0.07821229,"width":0.022938829,"height":0.01915403},"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"bounds":{"left":0.8088431,"top":0.08220271,"width":0.0019946808,"height":0.011173184},"on_screen":true,"role_description":"link","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Close","depth":4,"bounds":{"left":0.97539896,"top":0.07821229,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}","depth":4,"bounds":{"left":0.52859044,"top":0.016759777,"width":0.47140956,"height":0.98324025},"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}","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.47041222,"top":0.17478053,"width":0.00731383,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"32","depth":4,"bounds":{"left":0.47972074,"top":0.17478053,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"bounds":{"left":0.49202126,"top":0.17478053,"width":0.007978723,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"23","depth":4,"bounds":{"left":0.50199467,"top":0.17478053,"width":0.010305851,"height":0.015163607},"on_screen":true,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.51396275,"top":0.17318435,"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.5212766,"top":0.17318435,"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\\ServiceTraits;\n\nuse Carbon\\Carbon;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\CollectionResponseAssociatedId;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Models\\Account;\nuse Exception;\nuse Jiminny\\Component\\DealInsights\\Forecast\\Forecast;\nuse Jiminny\\Jobs\\Crm\\MatchActivitiesToNewOpportunity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Models\\Opportunity;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\DealFieldsService;\nuse Jiminny\\Services\\Crm\\Hubspot\\OpportunitySyncStrategy\\HubspotSingleSyncStrategy;\nuse Jiminny\\Services\\Crm\\Hubspot\\WebhookSyncBatchProcessor;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Utils\\CurrencyFormatter;\n\n/**\n * Optimized sync methods for better performance\n * These methods can be integrated into SyncCrmEntitiesTrait for significant performance gains\n */\ntrait OpportunitySyncTrait\n{\n private const int BATCH_SIZE = 100;\n private const int BATCH_PROCESS_SIZE = 800;\n\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected DealFieldsService $dealFieldsService;\n\n private ?array $cachedClosedDealStages = null;\n private array $cachedBusinessProcesses = [];\n private array $cachedStages = [];\n /** @var array<string, array<string>> keyed by config id */\n private array $cachedOpportunitySyncableFields = [];\n /** @var array<string, mixed> keyed by configId:ownerId */\n private array $cachedOwnerProfiles = [];\n /** @var array<string, mixed> keyed by configId:businessProcessId */\n private array $cachedRecordTypes = [];\n\n public function syncOpportunities(array $parameters, ?string $strategy = null): int\n {\n $startTime = microtime(true);\n $strategies = $this->opportunitySyncStrategyResolver->getStrategies($this->config, $strategy);\n $parameters['config'] = $this->config;\n $syncCount = 0;\n $reportedTotal = 0;\n $lastSyncedId = [];\n $strategyNames = [];\n\n try {\n foreach ($strategies as $strategyName => $syncStrategy) {\n $strategyNames[] = $strategyName;\n $this->logger->info(\n '[' . $this->getDisplayName() . '] Syncing opportunities using strategy: ' . $strategyName,\n ['team' => $this->team->getId()]\n );\n\n $total = 0;\n $lastId = null;\n $buffer = [];\n\n // HubspotWebhookBatchSyncStrategy returns empty generator, this is for other strategies\n foreach ($syncStrategy->fetchOpportunities($parameters, $total, $lastId) as $hsOpportunity) {\n $buffer[] = $hsOpportunity;\n\n // process every 800 rows (fits < 1 000 association limit)\n if (\\count($buffer) >= self::BATCH_PROCESS_SIZE) {\n $syncCount += $this->processOpportunityBatch($buffer);\n $buffer = [];\n }\n }\n\n // leftovers\n if ($buffer) {\n $syncCount += $this->processOpportunityBatch($buffer);\n }\n\n $reportedTotal += $total;\n $lastSyncedId = $lastId;\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException | CrmException $e) {\n $this->handleSyncException($e, $parameters);\n }\n\n $durationMs = round((microtime(true) - $startTime) * 1000, 2);\n $this->logger->info(\n '[HubSpot] Synced opportunities',\n [\n 'team' => $this->team->getId(),\n 'strategies' => implode(',', $strategyNames),\n 'sync_count' => $syncCount,\n 'total' => $reportedTotal,\n 'last_synced_id' => $lastSyncedId,\n 'duration_ms' => $durationMs,\n ]\n );\n\n return $reportedTotal;\n }\n\n private function handleSyncException(\\Throwable $e, array $parameters): void\n {\n if (($parameters['since'] ?? null) instanceof Carbon) {\n $parameters['since'] = $parameters['since']->toDateTimeString();\n }\n $parameters['config'] = $this->config->getId();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Sync opportunities failed', [\n 'teamId' => $this->team->getUuid(),\n 'parameters' => $parameters,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n /**\n * @inheritdoc\n */\n public function syncOpportunity(string $crmId): ?Opportunity\n {\n $this->client->getOpportunityById($crmId, ['hs_object_id', 'dealname']);\n return null;\n $strategy = $this->opportunitySyncStrategyResolver->resolve(\n $this->config,\n OpportunitySyncStrategyResolver::SINGLE_SYNC_OPPORTUNITY_STRATEGY,\n );\n\n $parameters = [\n 'config' => $this->config,\n 'crm_id' => $crmId,\n ];\n\n try {\n if (! $strategy instanceof HubspotSingleSyncStrategy) {\n throw new InvalidArgumentException('Strategy must by HubspotSingleSyncStrategy');\n }\n\n $hsOpportunity = $strategy->fetchOpportunity($parameters);\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Opportunity not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n $hsOpportunity['associations'] = $this->convertDealAssociations($hsOpportunity['associations'] ?? []);\n\n return $this->importOrUpdateOpportunity($hsOpportunity);\n }\n\n /**\n * Process webhook-collected opportunity batches.\n *\n * Drains Redis sets containing company CRM IDs collected from webhook events\n * and dispatches ImportOpportunityBatch jobs for batch processing.\n *\n * @return int Number of opportunity IDs dispatched to jobs\n */\n public function batchSyncOpportunities(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_DEAL,\n $configId\n );\n }\n\n /**\n * Import a batch of opportunities by their CRM IDs.\n * Fetches opportunity data from HubSpot API and delegates to importOpportunityBatch().\n *\n * @param array<string> $crmIds HubSpot deal CRM IDs\n *\n * @return array{success: array, failed_ids: array, errors?: array<string, string>}\n */\n public function importOpportunityBatchByIds(array $crmIds): array\n {\n $fields = $this->dealFieldsService->getFieldsForConfiguration($this->config);\n\n $allDeals = [];\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n $deals = $this->client->getOpportunitiesByIds($chunk, $fields);\n foreach ($deals as $deal) {\n $allDeals[] = $deal;\n }\n }\n\n // IDs not returned by HubSpot are likely deleted or inaccessible deals.\n // These are not failures — retrying won't bring them back.\n $fetchedIds = array_map('strval', array_column($allDeals, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] CRM IDs not found in HubSpot (likely deleted)', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allDeals),\n ]);\n }\n\n if (empty($allDeals)) {\n return ['success' => [], 'failed_ids' => []];\n }\n\n return $this->importOpportunityBatch($allDeals);\n }\n\n private function getClosedDealStages(): array\n {\n if ($this->cachedClosedDealStages !== null) {\n return $this->cachedClosedDealStages;\n }\n\n $stages = $this->crmEntityRepository->getOpportunityClosedStages($this->config);\n $data = [\n 'lost' => [],\n 'won' => [],\n ];\n\n foreach ($stages as $stage) {\n if ($stage->probability == 0.00) {\n $data['lost'][] = $stage->crm_provider_id;\n }\n if ($stage->probability == 100.00) {\n $data['won'][] = $stage->crm_provider_id;\n }\n }\n\n $this->cachedClosedDealStages = $data;\n\n return $data;\n }\n\n /**\n * Import deals into the database with pre-fetched associations.\n *\n * API calls here (getAssociationsData, getExistingOpportunityCrmIds) are NOT\n * caught — if they throw, the exception propagates to ImportOpportunityBatch::handle()\n * where Laravel retries the whole job with backoff. After all retries exhausted,\n * failed() requeues all IDs to Redis.\n *\n * The per-deal loop catches exceptions individually. A deal can end up in three states:\n * - success: imported/updated successfully\n * - failed_ids: exception thrown (DB constraint violation, corrupt data, etc.)\n * These are permanent issues — retrying won't fix them.\n * - skipped (null): missing dependencies (no account, unknown pipeline/stage).\n * This is acceptable — the deal cannot be imported until those exist.\n */\n private function importOpportunityBatch(array $deals): array\n {\n $syncedOpportunities = [\n 'success' => [],\n 'failed_ids' => [],\n ];\n $dealIds = array_column($deals, 'id');\n $batchStart = microtime(true);\n $slowDeals = [];\n\n // Shared association/existing-ID preparation is batch-level state. If it fails, rethrow so the\n // queue job retries the whole batch and eventually requeues all deal IDs back to Redis.\n try {\n $companyAssocStart = microtime(true);\n $companyAssociations = $this->client->getAssociationsData($dealIds, 'deals', 'companies');\n $companyAssocMs = (int) round((microtime(true) - $companyAssocStart) * 1000);\n\n $contactAssocStart = microtime(true);\n $contactAssociations = $this->client->getAssociationsData($dealIds, 'deals', 'contacts');\n $contactAssocMs = (int) round((microtime(true) - $contactAssocStart) * 1000);\n\n $prepareStart = microtime(true);\n $allCompanyIds = $this->flattenAssociationIds($companyAssociations);\n $allContactIds = $this->flattenAssociationIds($contactAssociations);\n $prepareTimings = [];\n $associationsData = $this->prepareAssociatedEntities(\n $companyAssociations,\n $contactAssociations,\n $prepareTimings\n );\n $prepareMs = (int) round((microtime(true) - $prepareStart) * 1000);\n\n $missingCompanies = count(array_diff(\n $allCompanyIds,\n array_keys($associationsData['company_id_mappings'] ?? [])\n ));\n $missingContacts = count(array_diff(\n $allContactIds,\n array_keys($associationsData['contact_id_mappings'] ?? [])\n ));\n\n $existingCrmIds = $this->crmEntityRepository->getExistingOpportunityCrmIds(\n $this->config,\n array_map('strval', $dealIds)\n );\n $existingCrmIdSet = array_flip($existingCrmIds);\n } catch (\\Throwable $e) {\n $this->logger->error('[' . $this->getDisplayName() . '] Failed to fetch associations or existing IDs', [\n 'teamId' => $this->team->getId(),\n 'dealCount' => count($dealIds),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n $loopStart = microtime(true);\n foreach ($deals as $deal) {\n $dealStart = microtime(true);\n\n try {\n $deal['associations'] = $this->prepareAssociationsForOpportunity(\n $deal['id'],\n $companyAssociations,\n $contactAssociations,\n $associationsData\n );\n\n $syncedOpportunity = $this->importOrUpdateOpportunity(\n $deal,\n isset($existingCrmIdSet[(string) $deal['id']])\n );\n if ($syncedOpportunity) {\n $syncedOpportunities['success'][] = $syncedOpportunity;\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import opportunity', [\n 'teamId' => $this->team->getId(),\n 'crmId' => $deal['id'],\n 'error' => $e->getMessage(),\n ]);\n $syncedOpportunities['failed_ids'][] = $deal['id'];\n $syncedOpportunities['errors'][$deal['id']] = $e->getMessage();\n }\n\n $dealMs = (int) round((microtime(true) - $dealStart) * 1000);\n if ($dealMs > 1000) {\n $slowDeals[] = ['crmId' => $deal['id'], 'ms' => $dealMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importOpportunityBatch timing', [\n 'teamId' => $this->team->getId(),\n 'deal_count' => count($deals),\n 'total_ms' => $totalMs,\n 'company_assoc_api_ms' => $companyAssocMs,\n 'contact_assoc_api_ms' => $contactAssocMs,\n 'prepare_entities_ms' => $prepareMs,\n 'prepare_accounts_ms' => $prepareTimings['accounts_ms'],\n 'prepare_contacts_ms' => $prepareTimings['contacts_ms'],\n 'total_companies' => count($allCompanyIds),\n 'missing_companies' => $missingCompanies,\n 'total_contacts' => count($allContactIds),\n 'missing_contacts' => $missingContacts,\n 'deals_loop_ms' => $loopMs,\n 'avg_deal_ms' => ! empty($deals) ? (int) round($loopMs / count($deals)) : 0,\n 'slow_deals_count' => count($slowDeals),\n 'slow_deals' => array_slice($slowDeals, 0, 10),\n ]);\n\n return $syncedOpportunities;\n }\n\n /**\n * Prepare associated entities for opportunities with optimized batch processing\n * Returns structured data with CRM ID to DB ID mappings for each opportunity\n */\n private function prepareAssociatedEntities(\n array $companyAssociations,\n array $contactAssociations,\n array &$timings = []\n ): array {\n // Step 1: Collect all unique company and contact IDs from associations\n $allCompanyIds = $this->flattenAssociationIds($companyAssociations);\n $allContactIds = $this->flattenAssociationIds($contactAssociations);\n\n // Step 2: Batch sync missing entities and get CRM ID to DB ID mappings\n $companyIdMappings = [];\n $contactIdMappings = [];\n $accountsMs = 0;\n $contactsMs = 0;\n\n if (! empty($allCompanyIds)) {\n $start = microtime(true);\n $companyIdMappings = $this->prepareAssociatedAccounts($allCompanyIds);\n $accountsMs = (int) round((microtime(true) - $start) * 1000);\n }\n\n if (! empty($allContactIds)) {\n $start = microtime(true);\n $contactIdMappings = $this->prepareAssociatedContacts($allContactIds);\n $contactsMs = (int) round((microtime(true) - $start) * 1000);\n }\n\n $timings = [\n 'accounts_ms' => $accountsMs,\n 'contacts_ms' => $contactsMs,\n ];\n\n return [\n 'company_id_mappings' => $companyIdMappings,\n 'contact_id_mappings' => $contactIdMappings,\n ];\n }\n\n /**\n * Flatten association data to get unique IDs\n */\n private function flattenAssociationIds(array $associations): array\n {\n $ids = [];\n foreach ($associations as $dealAssociations) {\n if (is_array($dealAssociations)) {\n foreach ($dealAssociations as $id) {\n $ids[$id] = true;\n }\n }\n }\n\n return array_keys($ids);\n }\n\n /**\n * Batch sync missing accounts\n */\n private function prepareAssociatedAccounts(array $companyIds): array\n {\n // Find which accounts already exist (lean covering-index lookup)\n $existingAccountsData = $this->crmEntityRepository\n ->getExistingAccountIdsMap($this->config, $companyIds);\n\n $missingCompanyIds = array_diff($companyIds, array_keys($existingAccountsData));\n\n if (empty($missingCompanyIds)) {\n return $existingAccountsData;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing accounts', [\n 'teamId' => $this->team->getUuid(),\n 'total_companies' => count($companyIds),\n 'existing_companies' => count($existingAccountsData),\n 'missing_companies' => count($missingCompanyIds),\n ]);\n\n // we already have limit on opportunity ids count\n // Initialize variable before try block\n $syncedAccountsData = [];\n\n try {\n $syncedAccountsData = $this->batchSyncCrmObjects('companies', $missingCompanyIds);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to sync missing accounts', [\n 'size' => count($missingCompanyIds),\n 'error' => $e->getMessage(),\n ]);\n $syncedAccountsData = [];\n }\n\n return $existingAccountsData + $syncedAccountsData;\n }\n\n /**\n * Prepare associated contacts - find existing and sync missing ones\n * Returns mapping of CRM ID to DB ID\n */\n private function prepareAssociatedContacts(array $contactIds): array\n {\n // Find which contacts already exist (lean covering-index lookup)\n $existingContactsData = $this->crmEntityRepository\n ->getExistingContactIdsMap($this->config, $contactIds);\n\n $missingContactIds = array_diff($contactIds, array_keys($existingContactsData));\n\n if (empty($missingContactIds)) {\n return $existingContactsData;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing contacts', [\n 'teamId' => $this->team->getUuid(),\n 'total_contacts' => count($contactIds),\n 'existing_contacts' => count($existingContactsData),\n 'missing_contacts' => count($missingContactIds),\n ]);\n\n // Sync missing contacts using batch API\n try {\n $syncedContactsData = $this->batchSyncCrmObjects('contacts', $missingContactIds);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to sync missing contacts', [\n 'size' => count($missingContactIds),\n 'error' => $e->getMessage(),\n ]);\n $syncedContactsData = [];\n }\n\n return $existingContactsData + $syncedContactsData;\n }\n\n private function batchSyncCrmObjects(string $objectType, array $crmIds): array\n {\n $syncObjects = [];\n $crmObjectIds = array_values($crmIds);\n\n foreach (array_chunk($crmObjectIds, self::BATCH_SIZE) as $chunk) {\n try {\n $objects = $objectType === 'companies' ?\n $this->client->getCompaniesByIds($chunk, $this->getCompanyFields()) :\n $this->client->getContactsByIds($chunk, $this->getContactFields());\n\n foreach ($objects as $objectId => $objectData) {\n $this->importCrmObject($objectType, (string) $objectId, $objectData, $syncObjects);\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch synced ' . $objectType, [\n 'requested_count' => count($chunk),\n 'synced_count' => count($objects),\n ]);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch ' . $objectType . ' sync failed', [\n 'ids' => $chunk,\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n return $syncObjects;\n }\n\n private function importCrmObject(string $objectType, string $objectId, mixed $objectData, array &$syncObjects): void\n {\n try {\n $object = $objectType === 'companies' ?\n $this->importAccount($objectData) :\n $this->importContact($objectData);\n\n if ($object) {\n $syncObjects[$object->getCrmProviderId()] = $object->getId();\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import batch ' . $objectType, [\n 'id' => $objectId,\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n /**\n * Prepare associations for a single opportunity\n *\n * The return value is an array with the following structure:\n * [\n * 'companies' => [\n * $companyCrmId => $companyId,\n * ...\n * ],\n * 'contacts' => [\n * $contactCrmId => $contactId,\n * ...\n * ],\n * 'account_id' => $accountId,\n * ]\n */\n private function prepareAssociationsForOpportunity(\n string $oppCrmId,\n array $companyAssociations,\n array $contactAssociations,\n array $associationsData\n ): array {\n $associations = [\n 'companies' => [],\n 'contacts' => [],\n 'account_id' => null, // Primary account for opportunity\n ];\n\n $oppCompanyIds = $companyAssociations[$oppCrmId] ?? [];\n foreach ($oppCompanyIds as $companyCrmId) {\n if (isset($associationsData['company_id_mappings'][$companyCrmId])) {\n $associations['companies'][$companyCrmId] = $associationsData['company_id_mappings'][$companyCrmId];\n\n // Set primary account (first company becomes primary account)\n if ($associations['account_id'] === null) {\n $associations['account_id'] = $associationsData['company_id_mappings'][$companyCrmId];\n }\n }\n }\n\n $oppContactIds = $contactAssociations[$oppCrmId] ?? [];\n foreach ($oppContactIds as $contactCrmId) {\n if (isset($associationsData['contact_id_mappings'][$contactCrmId])) {\n $associations['contacts'][$contactCrmId] = $associationsData['contact_id_mappings'][$contactCrmId];\n }\n }\n\n return $associations;\n }\n\n /**\n * Update only associations for an opportunity\n */\n private function updateOpportunityAssociations(Opportunity $opportunity, array $associations): void\n {\n // Update contact associations\n $this->importOpportunityContacts($opportunity, $associations['contacts']);\n\n // Update company (account) associations\n $this->updateOpportunityAccount($opportunity, $associations['account_id']);\n }\n\n /**\n * Remove all contact associations from an opportunity\n */\n private function removeAllOpportunityContacts(Opportunity $opportunity): void\n {\n $currentCount = (int) $opportunity->contacts()->count();\n\n if ($currentCount > 0) {\n $opportunity->contacts()->detach();\n\n $this->logger->info('[' . $this->getDisplayName() . '] Removed all contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'removed_count' => $currentCount,\n ]);\n }\n }\n\n private function updateOpportunityAccount(Opportunity $opportunity, ?int $accountId): void\n {\n if ($accountId === null) {\n // No account ID provided - keep current account\n return;\n }\n\n $currentAccountId = $opportunity->getAccountId();\n\n // Only update if account has changed\n if ($currentAccountId !== $accountId) {\n $opportunity->account_id = $accountId;\n $opportunity->save();\n\n $this->logger->info('[' . $this->getDisplayName() . '] Updated opportunity account association', [\n 'opportunity_id' => $opportunity->getId(),\n 'old_account_id' => $currentAccountId,\n 'new_account_id' => $accountId,\n ]);\n }\n }\n\n /**\n * Find existing opportunities by external IDs (OPTIMIZED VERSION)\n * Uses batch query for better performance\n */\n private function findExistingOpportunities(array $crmIds): Collection\n {\n return $this->crmEntityRepository\n ->findOpportunitiesByExternalIds($this->config, $crmIds);\n }\n\n private function processOpportunityBatch(array $opportunities): int\n {\n $syncedOpportunities = $this->importOpportunityBatch($opportunities);\n\n return count($syncedOpportunities['success'] ?? []);\n }\n\n /**\n * Convert single deal associations from HubSpot format to internal format\n * Handles both HubSpot SDK objects and array formats\n *\n * @param array $opportunityAssociations Raw associations from HubSpot API or pre-processed\n *\n * @return array Processed associations with DB IDs\n */\n private function convertDealAssociations(array $opportunityAssociations): array\n {\n $associations = $this->initializeAssociationsStructure();\n\n if (empty($opportunityAssociations)) {\n return $associations;\n }\n\n $associationIds = $this->extractAssociationIds($opportunityAssociations);\n\n $this->processCompanyAssociations($associationIds, $associations);\n $this->processContactAssociations($associationIds, $associations);\n\n return $associations;\n }\n\n private function initializeAssociationsStructure(): array\n {\n return [\n 'companies' => [],\n 'contacts' => [],\n 'account_id' => null, // Primary account for opportunity\n ];\n }\n\n private function extractAssociationIds(array $opportunityAssociations): array\n {\n $associationIds = [];\n\n foreach ($opportunityAssociations as $type => $associationData) {\n if (! empty($associationData)) {\n $associationIds[$type] = $this->convertSingleDealAssociations($associationData);\n }\n }\n\n return $associationIds;\n }\n\n private function processCompanyAssociations(array $associationIds, array &$associations): void\n {\n if (empty($associationIds['companies'])) {\n return;\n }\n\n $companyId = $associationIds['companies'][0];\n $account = $this->findOrSyncAccount($companyId);\n\n if ($account instanceof Account) {\n $associations['companies'][$companyId] = $account->getId();\n $associations['account_id'] = $account->getId();\n }\n }\n\n private function processContactAssociations(array $associationIds, array &$associations): void\n {\n if (empty($associationIds['contacts'])) {\n return;\n }\n\n foreach ($associationIds['contacts'] as $contactId) {\n $contact = $this->findOrSyncContact($contactId);\n\n if ($contact instanceof Contact) {\n $associations['contacts'][$contactId] = $contact->getId();\n }\n }\n }\n\n private function findOrSyncAccount(string $companyId): ?Account\n {\n $account = $this->crmEntityRepository->findAccountByExternalId($this->config, $companyId);\n\n if (! $account instanceof Account) {\n $account = $this->syncAccount($companyId);\n }\n\n return $account;\n }\n\n private function findOrSyncContact(string $contactId): ?Contact\n {\n $contact = $this->crmEntityRepository->findContactByExternalId($this->config, $contactId);\n\n if (! $contact instanceof Contact) {\n $contact = $this->syncContact($contactId);\n }\n\n return $contact;\n }\n\n private function convertSingleDealAssociations($opportunityAssociations = null): array\n {\n $associationData = [];\n\n if ($opportunityAssociations === null) {\n return $associationData;\n }\n\n // Handle array input (from extractAssociationIds)\n if (is_array($opportunityAssociations)) {\n return $opportunityAssociations;\n }\n\n // Handle CollectionResponseAssociatedId object\n if ($opportunityAssociations instanceof CollectionResponseAssociatedId) {\n foreach ($opportunityAssociations->getResults() as $association) {\n $associationData[] = $association->getId();\n }\n }\n\n return $associationData;\n }\n\n private function importOrUpdateOpportunity($crmData, ?bool $exists = null): ?Opportunity\n {\n if (empty($crmData['properties'])) {\n return null;\n }\n\n $crmId = (string) $crmData['id'];\n $properties = $crmData['properties'];\n $associations = $crmData['associations'] ?? [];\n\n $opportunityExists = $exists ?? (bool) $this->crmEntityRepository->findOpportunityByExternalId(\n $this->config,\n $crmId\n );\n\n if ($opportunityExists) {\n return $this->updateOpportunity($crmId, $properties, $associations);\n }\n\n return $this->createOpportunity($crmId, $properties, $associations);\n }\n\n /**\n * Create new opportunity\n */\n private function createOpportunity(string $crmId, array $properties, array $associations): ?Opportunity\n {\n $accountId = $this->resolveAccountId($associations);\n if (! $accountId) {\n return null;\n }\n\n $businessProcess = $this->resolveBusinessProcess($properties['pipeline'] ?? null);\n if (! $businessProcess) {\n return null;\n }\n\n $stage = $this->resolveStage($businessProcess, $properties['dealstage'] ?? null);\n if (! $stage) {\n return null;\n }\n\n $data = $this->buildOpportunityData($properties, $accountId, $businessProcess, $stage);\n\n $attributes = [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $crmId,\n ];\n\n $values = array_merge($attributes, $data);\n\n $opportunity = $this->crmEntityRepository->upsertOpportunity($attributes, $values);\n\n $this->importExternalFieldData($properties, $opportunity->getId());\n $this->importOpportunityContacts($opportunity, $associations['contacts']);\n\n if ($opportunity->wasRecentlyCreated) {\n MatchActivitiesToNewOpportunity::dispatch($opportunity->getId());\n }\n\n return $opportunity;\n }\n\n /**\n * Update existing opportunity\n */\n private function updateOpportunity(string $crmId, array $properties, array $associations): Opportunity\n {\n $accountId = $this->resolveAccountId($associations);\n $businessProcess = $this->resolveBusinessProcess($properties['pipeline'] ?? null);\n $stage = $businessProcess ? $this->resolveStage($businessProcess, $properties['dealstage'] ?? null) : null;\n\n $data = $this->buildOpportunityData($properties, $accountId, $businessProcess, $stage);\n\n $attributes = [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $crmId,\n ];\n\n $values = array_merge($attributes, $data);\n $opportunity = $this->crmEntityRepository->upsertOpportunity($attributes, $values);\n\n $this->importExternalFieldData($properties, $opportunity->getId());\n $this->updateOpportunityAssociations($opportunity, $associations);\n\n return $opportunity;\n }\n\n private function resolveAccountId(array $associations): ?int\n {\n if (! empty($associations['account_id'])) {\n return $associations['account_id'];\n }\n\n if (empty($associations)) {\n return null;\n }\n\n // Fallback: use first company as account (currently SDK returns one company)\n foreach ($associations['companies'] as $accountId) {\n return $accountId;\n }\n\n return null;\n }\n\n private function buildOpportunityData(\n array $properties,\n ?int $accountId,\n ?BusinessProcess $businessProcess,\n ?Stage $stage\n ): array {\n $ownerId = null;\n $profile = null;\n if (! empty($properties['hubspot_owner_id'])) {\n $ownerId = $properties['hubspot_owner_id'];\n $profile = $this->getCachedOwnerProfile((string) $ownerId);\n }\n\n $name = 'Unknown';\n if (isset($properties['dealname'])) {\n $name = mb_strimwidth($properties['dealname'], 0, 128);\n }\n\n $amount = $this->resolveAmount($properties);\n $currency = $properties['deal_currency_code'] ?? null;\n\n $closeDate = null;\n if (! empty($properties['closedate'])) {\n $closeDate = Carbon::parse($properties['closedate'])->format('Y-m-d');\n }\n\n $remotelyCreatedAt = null;\n if (! empty($properties['createdate']) && strtotime($properties['createdate'])) {\n $date = $this->parseCleanDatetime($properties['createdate']);\n $remotelyCreatedAt = $date?->format('Y-m-d H:i:s');\n }\n\n $closedStages = $this->getClosedDealStages();\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $data = [\n 'team_id' => $this->team->getId(),\n 'user_id' => $profile ? $profile->user_id : null,\n 'owner_id' => $ownerId,\n 'name' => $name,\n 'value' => ! empty($amount) ? $amount : null,\n 'currency_code' => CurrencyFormatter::formatCode($currency),\n 'close_date' => $closeDate,\n 'is_closed' => $isWon || $isLost,\n 'is_won' => $isWon,\n 'remotely_created_at' => $remotelyCreatedAt,\n 'probability' => $this->resolveDealProbability($properties['hs_deal_stage_probability']),\n 'forecast_category' => $this->resolveForecastCategory($properties['hs_manual_forecast_category']),\n ];\n\n if ($accountId) {\n $data['account_id'] = $accountId;\n }\n\n if ($stage) {\n $data['stage_id'] = $stage->id;\n }\n\n if ($businessProcess) {\n $recordType = $this->getCachedBusinessProcessRecordType($businessProcess);\n if ($recordType) {\n $data['record_type_id'] = $recordType->id;\n }\n }\n\n return $data;\n }\n\n private function getCachedOwnerProfile(string $ownerId): mixed\n {\n $cacheKey = $this->config->getId() . ':' . $ownerId;\n if (array_key_exists($cacheKey, $this->cachedOwnerProfiles)) {\n return $this->cachedOwnerProfiles[$cacheKey];\n }\n\n $profile = $this->crmEntityRepository->findProfileByExternalId($this->config, $ownerId);\n $this->cachedOwnerProfiles[$cacheKey] = $profile;\n\n return $profile;\n }\n\n private function getCachedBusinessProcessRecordType(BusinessProcess $businessProcess): mixed\n {\n $cacheKey = $this->config->getId() . ':' . $businessProcess->getId();\n if (array_key_exists($cacheKey, $this->cachedRecordTypes)) {\n return $this->cachedRecordTypes[$cacheKey];\n }\n\n $recordType = $this->crmEntityRepository->getBusinessProcessRecordType($businessProcess);\n $this->cachedRecordTypes[$cacheKey] = $recordType;\n\n return $recordType;\n }\n\n private function resolveBusinessProcess(?string $pipelineId): ?BusinessProcess\n {\n if ($pipelineId === null) {\n return null;\n }\n\n $cacheKey = $this->getBusinessProcessCacheKey($pipelineId);\n if (isset($this->cachedBusinessProcesses[$cacheKey])) {\n return $this->cachedBusinessProcesses[$cacheKey];\n }\n\n $businessProcess = $this->getBusinessProcess($pipelineId);\n\n if (! $businessProcess instanceof BusinessProcess) {\n $this->importStages();\n $businessProcess = $this->getBusinessProcess($pipelineId);\n }\n\n if (! $businessProcess instanceof BusinessProcess) {\n $this->logger->info(\n '[HubSpot] Deal is not attached to a pipeline',\n [\n 'pipeline' => $pipelineId]\n );\n }\n\n $this->cachedBusinessProcesses[$cacheKey] = $businessProcess;\n\n return $businessProcess;\n }\n\n private function getBusinessProcess(string $pipelineId): ?BusinessProcess\n {\n return $this->crmEntityRepository->findBusinessProcessesByExternalId($this->config, $pipelineId);\n }\n\n private function getBusinessProcessCacheKey(string $pipelineId): string\n {\n return $this->config->getId() . '_' . $pipelineId;\n }\n\n private function resolveStage(BusinessProcess $businessProcess, ?string $stageId): ?Stage\n {\n if (empty($stageId)) {\n return null;\n }\n\n $cacheKey = $this->config->getId() . ':' . $businessProcess->getId() . ':' . $stageId;\n if (isset($this->cachedStages[$cacheKey])) {\n return $this->cachedStages[$cacheKey];\n }\n\n $stage = $this->crmEntityRepository->getPipelineStageByConditions(\n $businessProcess,\n [\n 'crm_provider_id' => $stageId,\n 'type' => Stage::TYPE_OPPORTUNITY,\n ]\n );\n\n if ($stage === null) {\n $this->importStages(null, $stageId);\n }\n\n if ($stage === null) {\n $this->logger->info('[HubSpot] Stage does not exist => ' . $stageId);\n }\n\n $this->cachedStages[$cacheKey] = $stage;\n\n return $stage;\n }\n\n private function resolveAmount(array $properties): ?string\n {\n $amount = null;\n if (! empty($properties['amount'])) {\n $amount = str_replace(',', '', $properties['amount']);\n }\n\n if ($this->config->hasDefaultCurrencyFieldSet()) {\n $valueFieldName = $this->config->getDefaultCurrencyField()->getCrmProviderId();\n $amount = $properties[$valueFieldName] ?? $amount;\n }\n\n return $amount;\n }\n\n private function parseCleanDatetime(string $datetime): ?Carbon\n {\n // Treat pre-1980 values as invalid\n $minValidDate = Carbon::parse('1980-01-01 00:00:00');\n\n try {\n $date = Carbon::parse($datetime);\n\n if ($minValidDate->gt($date)) {\n return null;\n }\n\n return $date;\n } catch (Exception) {\n return null; // On parse error, treat as null\n }\n }\n\n private function resolveDealProbability(?string $stageProbability): int\n {\n if ($stageProbability === null) {\n return 0;\n }\n\n $probability = (float) $stageProbability;\n\n return $probability > 1 ? 0 : (int) ($probability * 100);\n }\n\n private function resolveForecastCategory(?string $forecastCategory): string\n {\n if (! $forecastCategory) {\n return Forecast::FORECAST_CATEGORY_UNCATEGORIZED;\n }\n\n $forecastCategory = str_replace('_', ' ', $forecastCategory);\n\n return ucwords(strtolower($forecastCategory));\n }\n\n private function importExternalFieldData(array $properties, int $opportunityId): void\n {\n $this->importOpportunityCrmFieldData(\n $properties,\n $this->getCachedOpportunitySyncableFields(),\n $opportunityId\n );\n }\n\n private function getCachedOpportunitySyncableFields(): array\n {\n $cacheKey = (string) $this->config->getId();\n if (! isset($this->cachedOpportunitySyncableFields[$cacheKey])) {\n $this->cachedOpportunitySyncableFields[$cacheKey] = $this->getOpportunitySyncableFields();\n }\n\n return $this->cachedOpportunitySyncableFields[$cacheKey];\n }\n\n private function importOpportunityContacts(Opportunity $opportunity, array $associations): void\n {\n // Handle empty or missing contact associations\n if (empty($associations)) {\n // Remove all existing contact associations if none provided\n $this->removeAllOpportunityContacts($opportunity);\n\n return;\n }\n\n // Use differential sync approach for better performance and accuracy\n $this->syncOpportunityContactsDifferential($opportunity, $associations);\n }\n\n /**\n * Sync opportunity contacts using differential approach\n * This compares current vs new associations and only makes necessary changes\n */\n private function syncOpportunityContactsDifferential(Opportunity $opportunity, array $contactAssociations): void\n {\n $currentContactCrmIds = $this->getCurrentContactCrmIds($opportunity);\n $contactAssociationIds = array_keys($contactAssociations);\n\n $contactsToAdd = array_diff($contactAssociationIds, $currentContactCrmIds);\n $contactsToRemove = array_diff($currentContactCrmIds, $contactAssociationIds);\n\n if (empty($contactsToAdd) && empty($contactsToRemove)) {\n return;\n }\n\n $this->logContactAssociationChanges($opportunity, $currentContactCrmIds, $contactAssociations, $contactsToAdd, $contactsToRemove);\n\n $this->removeContactAssociations($opportunity, $contactsToRemove);\n $this->addContactAssociations($opportunity, $contactsToAdd, $contactAssociations);\n }\n\n private function getCurrentContactCrmIds(Opportunity $opportunity): array\n {\n return $opportunity->contacts()\n ->pluck('contacts.crm_provider_id')\n ->toArray();\n }\n\n private function logContactAssociationChanges(\n Opportunity $opportunity,\n array $currentContactCrmIds,\n array $contactAssociations,\n array $contactsToAdd,\n array $contactsToRemove\n ): void {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact association changes', [\n 'opportunity_id' => $opportunity->getId(),\n 'current_contacts' => $currentContactCrmIds,\n 'new_contacts' => $contactAssociations,\n 'contacts_to_add' => $contactsToAdd,\n 'contacts_to_remove' => $contactsToRemove,\n ]);\n }\n\n private function removeContactAssociations(Opportunity $opportunity, array $contactsToRemove): void\n {\n if (empty($contactsToRemove)) {\n return;\n }\n\n $contactsToDetach = $opportunity->contacts()\n ->whereIn('contacts.crm_provider_id', $contactsToRemove)\n ->pluck('contacts.id')\n ->toArray();\n\n if (! empty($contactsToDetach)) {\n $opportunity->contacts()->detach($contactsToDetach);\n\n $this->logger->info('[' . $this->getDisplayName() . '] Removed contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'removed_contact_crm_ids' => $contactsToRemove,\n 'removed_contact_count' => count($contactsToDetach),\n ]);\n }\n }\n\n private function addContactAssociations(Opportunity $opportunity, array $contactsToAdd, array $contactAssociations): void\n {\n if (empty($contactsToAdd)) {\n return;\n }\n\n $contactsAdded = [];\n foreach ($contactsToAdd as $crmId) {\n $id = $contactAssociations[$crmId];\n\n if ($this->attachSingleContact($opportunity, (string) $crmId, $id)) {\n $contactsAdded[] = $crmId;\n }\n }\n\n $this->logAddedContacts($opportunity, $contactsAdded);\n }\n\n private function attachSingleContact(Opportunity $opportunity, string $crmId, int $id): bool\n {\n try {\n return $this->performContactAttachment($opportunity, $id, $crmId);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to add contact association', [\n 'opportunity_id' => $opportunity->getId(),\n 'contact_crm_id' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n private function performContactAttachment(Opportunity $opportunity, int $contactId, string $crmId): bool\n {\n try {\n $opportunity->contacts()->attach($contactId, [\n 'crm_provider_id' => $crmId,\n ]);\n\n return true;\n } catch (\\Illuminate\\Database\\QueryException $e) {\n if (str_contains($e->getMessage(), 'Duplicate entry')) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact association already exists', [\n 'contact_id' => $contactId,\n 'contact_crm_id' => $crmId,\n 'opportunity_id' => $opportunity->getId(),\n ]);\n\n return false;\n }\n\n throw $e;\n }\n }\n\n private function logAddedContacts(Opportunity $opportunity, array $contactsAdded): void\n {\n if (! empty($contactsAdded)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Added contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'added_contact_crm_ids' => $contactsAdded,\n 'added_contacts_count' => count($contactsAdded),\n ]);\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits;\n\nuse Carbon\\Carbon;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\CollectionResponseAssociatedId;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Models\\Account;\nuse Exception;\nuse Jiminny\\Component\\DealInsights\\Forecast\\Forecast;\nuse Jiminny\\Jobs\\Crm\\MatchActivitiesToNewOpportunity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Models\\Opportunity;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\DealFieldsService;\nuse Jiminny\\Services\\Crm\\Hubspot\\OpportunitySyncStrategy\\HubspotSingleSyncStrategy;\nuse Jiminny\\Services\\Crm\\Hubspot\\WebhookSyncBatchProcessor;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Utils\\CurrencyFormatter;\n\n/**\n * Optimized sync methods for better performance\n * These methods can be integrated into SyncCrmEntitiesTrait for significant performance gains\n */\ntrait OpportunitySyncTrait\n{\n private const int BATCH_SIZE = 100;\n private const int BATCH_PROCESS_SIZE = 800;\n\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected DealFieldsService $dealFieldsService;\n\n private ?array $cachedClosedDealStages = null;\n private array $cachedBusinessProcesses = [];\n private array $cachedStages = [];\n /** @var array<string, array<string>> keyed by config id */\n private array $cachedOpportunitySyncableFields = [];\n /** @var array<string, mixed> keyed by configId:ownerId */\n private array $cachedOwnerProfiles = [];\n /** @var array<string, mixed> keyed by configId:businessProcessId */\n private array $cachedRecordTypes = [];\n\n public function syncOpportunities(array $parameters, ?string $strategy = null): int\n {\n $startTime = microtime(true);\n $strategies = $this->opportunitySyncStrategyResolver->getStrategies($this->config, $strategy);\n $parameters['config'] = $this->config;\n $syncCount = 0;\n $reportedTotal = 0;\n $lastSyncedId = [];\n $strategyNames = [];\n\n try {\n foreach ($strategies as $strategyName => $syncStrategy) {\n $strategyNames[] = $strategyName;\n $this->logger->info(\n '[' . $this->getDisplayName() . '] Syncing opportunities using strategy: ' . $strategyName,\n ['team' => $this->team->getId()]\n );\n\n $total = 0;\n $lastId = null;\n $buffer = [];\n\n // HubspotWebhookBatchSyncStrategy returns empty generator, this is for other strategies\n foreach ($syncStrategy->fetchOpportunities($parameters, $total, $lastId) as $hsOpportunity) {\n $buffer[] = $hsOpportunity;\n\n // process every 800 rows (fits < 1 000 association limit)\n if (\\count($buffer) >= self::BATCH_PROCESS_SIZE) {\n $syncCount += $this->processOpportunityBatch($buffer);\n $buffer = [];\n }\n }\n\n // leftovers\n if ($buffer) {\n $syncCount += $this->processOpportunityBatch($buffer);\n }\n\n $reportedTotal += $total;\n $lastSyncedId = $lastId;\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException | CrmException $e) {\n $this->handleSyncException($e, $parameters);\n }\n\n $durationMs = round((microtime(true) - $startTime) * 1000, 2);\n $this->logger->info(\n '[HubSpot] Synced opportunities',\n [\n 'team' => $this->team->getId(),\n 'strategies' => implode(',', $strategyNames),\n 'sync_count' => $syncCount,\n 'total' => $reportedTotal,\n 'last_synced_id' => $lastSyncedId,\n 'duration_ms' => $durationMs,\n ]\n );\n\n return $reportedTotal;\n }\n\n private function handleSyncException(\\Throwable $e, array $parameters): void\n {\n if (($parameters['since'] ?? null) instanceof Carbon) {\n $parameters['since'] = $parameters['since']->toDateTimeString();\n }\n $parameters['config'] = $this->config->getId();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Sync opportunities failed', [\n 'teamId' => $this->team->getUuid(),\n 'parameters' => $parameters,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n /**\n * @inheritdoc\n */\n public function syncOpportunity(string $crmId): ?Opportunity\n {\n $this->client->getOpportunityById($crmId, ['hs_object_id', 'dealname']);\n return null;\n $strategy = $this->opportunitySyncStrategyResolver->resolve(\n $this->config,\n OpportunitySyncStrategyResolver::SINGLE_SYNC_OPPORTUNITY_STRATEGY,\n );\n\n $parameters = [\n 'config' => $this->config,\n 'crm_id' => $crmId,\n ];\n\n try {\n if (! $strategy instanceof HubspotSingleSyncStrategy) {\n throw new InvalidArgumentException('Strategy must by HubspotSingleSyncStrategy');\n }\n\n $hsOpportunity = $strategy->fetchOpportunity($parameters);\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Opportunity not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n $hsOpportunity['associations'] = $this->convertDealAssociations($hsOpportunity['associations'] ?? []);\n\n return $this->importOrUpdateOpportunity($hsOpportunity);\n }\n\n /**\n * Process webhook-collected opportunity batches.\n *\n * Drains Redis sets containing company CRM IDs collected from webhook events\n * and dispatches ImportOpportunityBatch jobs for batch processing.\n *\n * @return int Number of opportunity IDs dispatched to jobs\n */\n public function batchSyncOpportunities(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_DEAL,\n $configId\n );\n }\n\n /**\n * Import a batch of opportunities by their CRM IDs.\n * Fetches opportunity data from HubSpot API and delegates to importOpportunityBatch().\n *\n * @param array<string> $crmIds HubSpot deal CRM IDs\n *\n * @return array{success: array, failed_ids: array, errors?: array<string, string>}\n */\n public function importOpportunityBatchByIds(array $crmIds): array\n {\n $fields = $this->dealFieldsService->getFieldsForConfiguration($this->config);\n\n $allDeals = [];\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n $deals = $this->client->getOpportunitiesByIds($chunk, $fields);\n foreach ($deals as $deal) {\n $allDeals[] = $deal;\n }\n }\n\n // IDs not returned by HubSpot are likely deleted or inaccessible deals.\n // These are not failures — retrying won't bring them back.\n $fetchedIds = array_map('strval', array_column($allDeals, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] CRM IDs not found in HubSpot (likely deleted)', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allDeals),\n ]);\n }\n\n if (empty($allDeals)) {\n return ['success' => [], 'failed_ids' => []];\n }\n\n return $this->importOpportunityBatch($allDeals);\n }\n\n private function getClosedDealStages(): array\n {\n if ($this->cachedClosedDealStages !== null) {\n return $this->cachedClosedDealStages;\n }\n\n $stages = $this->crmEntityRepository->getOpportunityClosedStages($this->config);\n $data = [\n 'lost' => [],\n 'won' => [],\n ];\n\n foreach ($stages as $stage) {\n if ($stage->probability == 0.00) {\n $data['lost'][] = $stage->crm_provider_id;\n }\n if ($stage->probability == 100.00) {\n $data['won'][] = $stage->crm_provider_id;\n }\n }\n\n $this->cachedClosedDealStages = $data;\n\n return $data;\n }\n\n /**\n * Import deals into the database with pre-fetched associations.\n *\n * API calls here (getAssociationsData, getExistingOpportunityCrmIds) are NOT\n * caught — if they throw, the exception propagates to ImportOpportunityBatch::handle()\n * where Laravel retries the whole job with backoff. After all retries exhausted,\n * failed() requeues all IDs to Redis.\n *\n * The per-deal loop catches exceptions individually. A deal can end up in three states:\n * - success: imported/updated successfully\n * - failed_ids: exception thrown (DB constraint violation, corrupt data, etc.)\n * These are permanent issues — retrying won't fix them.\n * - skipped (null): missing dependencies (no account, unknown pipeline/stage).\n * This is acceptable — the deal cannot be imported until those exist.\n */\n private function importOpportunityBatch(array $deals): array\n {\n $syncedOpportunities = [\n 'success' => [],\n 'failed_ids' => [],\n ];\n $dealIds = array_column($deals, 'id');\n $batchStart = microtime(true);\n $slowDeals = [];\n\n // Shared association/existing-ID preparation is batch-level state. If it fails, rethrow so the\n // queue job retries the whole batch and eventually requeues all deal IDs back to Redis.\n try {\n $companyAssocStart = microtime(true);\n $companyAssociations = $this->client->getAssociationsData($dealIds, 'deals', 'companies');\n $companyAssocMs = (int) round((microtime(true) - $companyAssocStart) * 1000);\n\n $contactAssocStart = microtime(true);\n $contactAssociations = $this->client->getAssociationsData($dealIds, 'deals', 'contacts');\n $contactAssocMs = (int) round((microtime(true) - $contactAssocStart) * 1000);\n\n $prepareStart = microtime(true);\n $allCompanyIds = $this->flattenAssociationIds($companyAssociations);\n $allContactIds = $this->flattenAssociationIds($contactAssociations);\n $prepareTimings = [];\n $associationsData = $this->prepareAssociatedEntities(\n $companyAssociations,\n $contactAssociations,\n $prepareTimings\n );\n $prepareMs = (int) round((microtime(true) - $prepareStart) * 1000);\n\n $missingCompanies = count(array_diff(\n $allCompanyIds,\n array_keys($associationsData['company_id_mappings'] ?? [])\n ));\n $missingContacts = count(array_diff(\n $allContactIds,\n array_keys($associationsData['contact_id_mappings'] ?? [])\n ));\n\n $existingCrmIds = $this->crmEntityRepository->getExistingOpportunityCrmIds(\n $this->config,\n array_map('strval', $dealIds)\n );\n $existingCrmIdSet = array_flip($existingCrmIds);\n } catch (\\Throwable $e) {\n $this->logger->error('[' . $this->getDisplayName() . '] Failed to fetch associations or existing IDs', [\n 'teamId' => $this->team->getId(),\n 'dealCount' => count($dealIds),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n $loopStart = microtime(true);\n foreach ($deals as $deal) {\n $dealStart = microtime(true);\n\n try {\n $deal['associations'] = $this->prepareAssociationsForOpportunity(\n $deal['id'],\n $companyAssociations,\n $contactAssociations,\n $associationsData\n );\n\n $syncedOpportunity = $this->importOrUpdateOpportunity(\n $deal,\n isset($existingCrmIdSet[(string) $deal['id']])\n );\n if ($syncedOpportunity) {\n $syncedOpportunities['success'][] = $syncedOpportunity;\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import opportunity', [\n 'teamId' => $this->team->getId(),\n 'crmId' => $deal['id'],\n 'error' => $e->getMessage(),\n ]);\n $syncedOpportunities['failed_ids'][] = $deal['id'];\n $syncedOpportunities['errors'][$deal['id']] = $e->getMessage();\n }\n\n $dealMs = (int) round((microtime(true) - $dealStart) * 1000);\n if ($dealMs > 1000) {\n $slowDeals[] = ['crmId' => $deal['id'], 'ms' => $dealMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importOpportunityBatch timing', [\n 'teamId' => $this->team->getId(),\n 'deal_count' => count($deals),\n 'total_ms' => $totalMs,\n 'company_assoc_api_ms' => $companyAssocMs,\n 'contact_assoc_api_ms' => $contactAssocMs,\n 'prepare_entities_ms' => $prepareMs,\n 'prepare_accounts_ms' => $prepareTimings['accounts_ms'],\n 'prepare_contacts_ms' => $prepareTimings['contacts_ms'],\n 'total_companies' => count($allCompanyIds),\n 'missing_companies' => $missingCompanies,\n 'total_contacts' => count($allContactIds),\n 'missing_contacts' => $missingContacts,\n 'deals_loop_ms' => $loopMs,\n 'avg_deal_ms' => ! empty($deals) ? (int) round($loopMs / count($deals)) : 0,\n 'slow_deals_count' => count($slowDeals),\n 'slow_deals' => array_slice($slowDeals, 0, 10),\n ]);\n\n return $syncedOpportunities;\n }\n\n /**\n * Prepare associated entities for opportunities with optimized batch processing\n * Returns structured data with CRM ID to DB ID mappings for each opportunity\n */\n private function prepareAssociatedEntities(\n array $companyAssociations,\n array $contactAssociations,\n array &$timings = []\n ): array {\n // Step 1: Collect all unique company and contact IDs from associations\n $allCompanyIds = $this->flattenAssociationIds($companyAssociations);\n $allContactIds = $this->flattenAssociationIds($contactAssociations);\n\n // Step 2: Batch sync missing entities and get CRM ID to DB ID mappings\n $companyIdMappings = [];\n $contactIdMappings = [];\n $accountsMs = 0;\n $contactsMs = 0;\n\n if (! empty($allCompanyIds)) {\n $start = microtime(true);\n $companyIdMappings = $this->prepareAssociatedAccounts($allCompanyIds);\n $accountsMs = (int) round((microtime(true) - $start) * 1000);\n }\n\n if (! empty($allContactIds)) {\n $start = microtime(true);\n $contactIdMappings = $this->prepareAssociatedContacts($allContactIds);\n $contactsMs = (int) round((microtime(true) - $start) * 1000);\n }\n\n $timings = [\n 'accounts_ms' => $accountsMs,\n 'contacts_ms' => $contactsMs,\n ];\n\n return [\n 'company_id_mappings' => $companyIdMappings,\n 'contact_id_mappings' => $contactIdMappings,\n ];\n }\n\n /**\n * Flatten association data to get unique IDs\n */\n private function flattenAssociationIds(array $associations): array\n {\n $ids = [];\n foreach ($associations as $dealAssociations) {\n if (is_array($dealAssociations)) {\n foreach ($dealAssociations as $id) {\n $ids[$id] = true;\n }\n }\n }\n\n return array_keys($ids);\n }\n\n /**\n * Batch sync missing accounts\n */\n private function prepareAssociatedAccounts(array $companyIds): array\n {\n // Find which accounts already exist (lean covering-index lookup)\n $existingAccountsData = $this->crmEntityRepository\n ->getExistingAccountIdsMap($this->config, $companyIds);\n\n $missingCompanyIds = array_diff($companyIds, array_keys($existingAccountsData));\n\n if (empty($missingCompanyIds)) {\n return $existingAccountsData;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing accounts', [\n 'teamId' => $this->team->getUuid(),\n 'total_companies' => count($companyIds),\n 'existing_companies' => count($existingAccountsData),\n 'missing_companies' => count($missingCompanyIds),\n ]);\n\n // we already have limit on opportunity ids count\n // Initialize variable before try block\n $syncedAccountsData = [];\n\n try {\n $syncedAccountsData = $this->batchSyncCrmObjects('companies', $missingCompanyIds);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to sync missing accounts', [\n 'size' => count($missingCompanyIds),\n 'error' => $e->getMessage(),\n ]);\n $syncedAccountsData = [];\n }\n\n return $existingAccountsData + $syncedAccountsData;\n }\n\n /**\n * Prepare associated contacts - find existing and sync missing ones\n * Returns mapping of CRM ID to DB ID\n */\n private function prepareAssociatedContacts(array $contactIds): array\n {\n // Find which contacts already exist (lean covering-index lookup)\n $existingContactsData = $this->crmEntityRepository\n ->getExistingContactIdsMap($this->config, $contactIds);\n\n $missingContactIds = array_diff($contactIds, array_keys($existingContactsData));\n\n if (empty($missingContactIds)) {\n return $existingContactsData;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing contacts', [\n 'teamId' => $this->team->getUuid(),\n 'total_contacts' => count($contactIds),\n 'existing_contacts' => count($existingContactsData),\n 'missing_contacts' => count($missingContactIds),\n ]);\n\n // Sync missing contacts using batch API\n try {\n $syncedContactsData = $this->batchSyncCrmObjects('contacts', $missingContactIds);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to sync missing contacts', [\n 'size' => count($missingContactIds),\n 'error' => $e->getMessage(),\n ]);\n $syncedContactsData = [];\n }\n\n return $existingContactsData + $syncedContactsData;\n }\n\n private function batchSyncCrmObjects(string $objectType, array $crmIds): array\n {\n $syncObjects = [];\n $crmObjectIds = array_values($crmIds);\n\n foreach (array_chunk($crmObjectIds, self::BATCH_SIZE) as $chunk) {\n try {\n $objects = $objectType === 'companies' ?\n $this->client->getCompaniesByIds($chunk, $this->getCompanyFields()) :\n $this->client->getContactsByIds($chunk, $this->getContactFields());\n\n foreach ($objects as $objectId => $objectData) {\n $this->importCrmObject($objectType, (string) $objectId, $objectData, $syncObjects);\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch synced ' . $objectType, [\n 'requested_count' => count($chunk),\n 'synced_count' => count($objects),\n ]);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch ' . $objectType . ' sync failed', [\n 'ids' => $chunk,\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n return $syncObjects;\n }\n\n private function importCrmObject(string $objectType, string $objectId, mixed $objectData, array &$syncObjects): void\n {\n try {\n $object = $objectType === 'companies' ?\n $this->importAccount($objectData) :\n $this->importContact($objectData);\n\n if ($object) {\n $syncObjects[$object->getCrmProviderId()] = $object->getId();\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import batch ' . $objectType, [\n 'id' => $objectId,\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n /**\n * Prepare associations for a single opportunity\n *\n * The return value is an array with the following structure:\n * [\n * 'companies' => [\n * $companyCrmId => $companyId,\n * ...\n * ],\n * 'contacts' => [\n * $contactCrmId => $contactId,\n * ...\n * ],\n * 'account_id' => $accountId,\n * ]\n */\n private function prepareAssociationsForOpportunity(\n string $oppCrmId,\n array $companyAssociations,\n array $contactAssociations,\n array $associationsData\n ): array {\n $associations = [\n 'companies' => [],\n 'contacts' => [],\n 'account_id' => null, // Primary account for opportunity\n ];\n\n $oppCompanyIds = $companyAssociations[$oppCrmId] ?? [];\n foreach ($oppCompanyIds as $companyCrmId) {\n if (isset($associationsData['company_id_mappings'][$companyCrmId])) {\n $associations['companies'][$companyCrmId] = $associationsData['company_id_mappings'][$companyCrmId];\n\n // Set primary account (first company becomes primary account)\n if ($associations['account_id'] === null) {\n $associations['account_id'] = $associationsData['company_id_mappings'][$companyCrmId];\n }\n }\n }\n\n $oppContactIds = $contactAssociations[$oppCrmId] ?? [];\n foreach ($oppContactIds as $contactCrmId) {\n if (isset($associationsData['contact_id_mappings'][$contactCrmId])) {\n $associations['contacts'][$contactCrmId] = $associationsData['contact_id_mappings'][$contactCrmId];\n }\n }\n\n return $associations;\n }\n\n /**\n * Update only associations for an opportunity\n */\n private function updateOpportunityAssociations(Opportunity $opportunity, array $associations): void\n {\n // Update contact associations\n $this->importOpportunityContacts($opportunity, $associations['contacts']);\n\n // Update company (account) associations\n $this->updateOpportunityAccount($opportunity, $associations['account_id']);\n }\n\n /**\n * Remove all contact associations from an opportunity\n */\n private function removeAllOpportunityContacts(Opportunity $opportunity): void\n {\n $currentCount = (int) $opportunity->contacts()->count();\n\n if ($currentCount > 0) {\n $opportunity->contacts()->detach();\n\n $this->logger->info('[' . $this->getDisplayName() . '] Removed all contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'removed_count' => $currentCount,\n ]);\n }\n }\n\n private function updateOpportunityAccount(Opportunity $opportunity, ?int $accountId): void\n {\n if ($accountId === null) {\n // No account ID provided - keep current account\n return;\n }\n\n $currentAccountId = $opportunity->getAccountId();\n\n // Only update if account has changed\n if ($currentAccountId !== $accountId) {\n $opportunity->account_id = $accountId;\n $opportunity->save();\n\n $this->logger->info('[' . $this->getDisplayName() . '] Updated opportunity account association', [\n 'opportunity_id' => $opportunity->getId(),\n 'old_account_id' => $currentAccountId,\n 'new_account_id' => $accountId,\n ]);\n }\n }\n\n /**\n * Find existing opportunities by external IDs (OPTIMIZED VERSION)\n * Uses batch query for better performance\n */\n private function findExistingOpportunities(array $crmIds): Collection\n {\n return $this->crmEntityRepository\n ->findOpportunitiesByExternalIds($this->config, $crmIds);\n }\n\n private function processOpportunityBatch(array $opportunities): int\n {\n $syncedOpportunities = $this->importOpportunityBatch($opportunities);\n\n return count($syncedOpportunities['success'] ?? []);\n }\n\n /**\n * Convert single deal associations from HubSpot format to internal format\n * Handles both HubSpot SDK objects and array formats\n *\n * @param array $opportunityAssociations Raw associations from HubSpot API or pre-processed\n *\n * @return array Processed associations with DB IDs\n */\n private function convertDealAssociations(array $opportunityAssociations): array\n {\n $associations = $this->initializeAssociationsStructure();\n\n if (empty($opportunityAssociations)) {\n return $associations;\n }\n\n $associationIds = $this->extractAssociationIds($opportunityAssociations);\n\n $this->processCompanyAssociations($associationIds, $associations);\n $this->processContactAssociations($associationIds, $associations);\n\n return $associations;\n }\n\n private function initializeAssociationsStructure(): array\n {\n return [\n 'companies' => [],\n 'contacts' => [],\n 'account_id' => null, // Primary account for opportunity\n ];\n }\n\n private function extractAssociationIds(array $opportunityAssociations): array\n {\n $associationIds = [];\n\n foreach ($opportunityAssociations as $type => $associationData) {\n if (! empty($associationData)) {\n $associationIds[$type] = $this->convertSingleDealAssociations($associationData);\n }\n }\n\n return $associationIds;\n }\n\n private function processCompanyAssociations(array $associationIds, array &$associations): void\n {\n if (empty($associationIds['companies'])) {\n return;\n }\n\n $companyId = $associationIds['companies'][0];\n $account = $this->findOrSyncAccount($companyId);\n\n if ($account instanceof Account) {\n $associations['companies'][$companyId] = $account->getId();\n $associations['account_id'] = $account->getId();\n }\n }\n\n private function processContactAssociations(array $associationIds, array &$associations): void\n {\n if (empty($associationIds['contacts'])) {\n return;\n }\n\n foreach ($associationIds['contacts'] as $contactId) {\n $contact = $this->findOrSyncContact($contactId);\n\n if ($contact instanceof Contact) {\n $associations['contacts'][$contactId] = $contact->getId();\n }\n }\n }\n\n private function findOrSyncAccount(string $companyId): ?Account\n {\n $account = $this->crmEntityRepository->findAccountByExternalId($this->config, $companyId);\n\n if (! $account instanceof Account) {\n $account = $this->syncAccount($companyId);\n }\n\n return $account;\n }\n\n private function findOrSyncContact(string $contactId): ?Contact\n {\n $contact = $this->crmEntityRepository->findContactByExternalId($this->config, $contactId);\n\n if (! $contact instanceof Contact) {\n $contact = $this->syncContact($contactId);\n }\n\n return $contact;\n }\n\n private function convertSingleDealAssociations($opportunityAssociations = null): array\n {\n $associationData = [];\n\n if ($opportunityAssociations === null) {\n return $associationData;\n }\n\n // Handle array input (from extractAssociationIds)\n if (is_array($opportunityAssociations)) {\n return $opportunityAssociations;\n }\n\n // Handle CollectionResponseAssociatedId object\n if ($opportunityAssociations instanceof CollectionResponseAssociatedId) {\n foreach ($opportunityAssociations->getResults() as $association) {\n $associationData[] = $association->getId();\n }\n }\n\n return $associationData;\n }\n\n private function importOrUpdateOpportunity($crmData, ?bool $exists = null): ?Opportunity\n {\n if (empty($crmData['properties'])) {\n return null;\n }\n\n $crmId = (string) $crmData['id'];\n $properties = $crmData['properties'];\n $associations = $crmData['associations'] ?? [];\n\n $opportunityExists = $exists ?? (bool) $this->crmEntityRepository->findOpportunityByExternalId(\n $this->config,\n $crmId\n );\n\n if ($opportunityExists) {\n return $this->updateOpportunity($crmId, $properties, $associations);\n }\n\n return $this->createOpportunity($crmId, $properties, $associations);\n }\n\n /**\n * Create new opportunity\n */\n private function createOpportunity(string $crmId, array $properties, array $associations): ?Opportunity\n {\n $accountId = $this->resolveAccountId($associations);\n if (! $accountId) {\n return null;\n }\n\n $businessProcess = $this->resolveBusinessProcess($properties['pipeline'] ?? null);\n if (! $businessProcess) {\n return null;\n }\n\n $stage = $this->resolveStage($businessProcess, $properties['dealstage'] ?? null);\n if (! $stage) {\n return null;\n }\n\n $data = $this->buildOpportunityData($properties, $accountId, $businessProcess, $stage);\n\n $attributes = [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $crmId,\n ];\n\n $values = array_merge($attributes, $data);\n\n $opportunity = $this->crmEntityRepository->upsertOpportunity($attributes, $values);\n\n $this->importExternalFieldData($properties, $opportunity->getId());\n $this->importOpportunityContacts($opportunity, $associations['contacts']);\n\n if ($opportunity->wasRecentlyCreated) {\n MatchActivitiesToNewOpportunity::dispatch($opportunity->getId());\n }\n\n return $opportunity;\n }\n\n /**\n * Update existing opportunity\n */\n private function updateOpportunity(string $crmId, array $properties, array $associations): Opportunity\n {\n $accountId = $this->resolveAccountId($associations);\n $businessProcess = $this->resolveBusinessProcess($properties['pipeline'] ?? null);\n $stage = $businessProcess ? $this->resolveStage($businessProcess, $properties['dealstage'] ?? null) : null;\n\n $data = $this->buildOpportunityData($properties, $accountId, $businessProcess, $stage);\n\n $attributes = [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $crmId,\n ];\n\n $values = array_merge($attributes, $data);\n $opportunity = $this->crmEntityRepository->upsertOpportunity($attributes, $values);\n\n $this->importExternalFieldData($properties, $opportunity->getId());\n $this->updateOpportunityAssociations($opportunity, $associations);\n\n return $opportunity;\n }\n\n private function resolveAccountId(array $associations): ?int\n {\n if (! empty($associations['account_id'])) {\n return $associations['account_id'];\n }\n\n if (empty($associations)) {\n return null;\n }\n\n // Fallback: use first company as account (currently SDK returns one company)\n foreach ($associations['companies'] as $accountId) {\n return $accountId;\n }\n\n return null;\n }\n\n private function buildOpportunityData(\n array $properties,\n ?int $accountId,\n ?BusinessProcess $businessProcess,\n ?Stage $stage\n ): array {\n $ownerId = null;\n $profile = null;\n if (! empty($properties['hubspot_owner_id'])) {\n $ownerId = $properties['hubspot_owner_id'];\n $profile = $this->getCachedOwnerProfile((string) $ownerId);\n }\n\n $name = 'Unknown';\n if (isset($properties['dealname'])) {\n $name = mb_strimwidth($properties['dealname'], 0, 128);\n }\n\n $amount = $this->resolveAmount($properties);\n $currency = $properties['deal_currency_code'] ?? null;\n\n $closeDate = null;\n if (! empty($properties['closedate'])) {\n $closeDate = Carbon::parse($properties['closedate'])->format('Y-m-d');\n }\n\n $remotelyCreatedAt = null;\n if (! empty($properties['createdate']) && strtotime($properties['createdate'])) {\n $date = $this->parseCleanDatetime($properties['createdate']);\n $remotelyCreatedAt = $date?->format('Y-m-d H:i:s');\n }\n\n $closedStages = $this->getClosedDealStages();\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $data = [\n 'team_id' => $this->team->getId(),\n 'user_id' => $profile ? $profile->user_id : null,\n 'owner_id' => $ownerId,\n 'name' => $name,\n 'value' => ! empty($amount) ? $amount : null,\n 'currency_code' => CurrencyFormatter::formatCode($currency),\n 'close_date' => $closeDate,\n 'is_closed' => $isWon || $isLost,\n 'is_won' => $isWon,\n 'remotely_created_at' => $remotelyCreatedAt,\n 'probability' => $this->resolveDealProbability($properties['hs_deal_stage_probability']),\n 'forecast_category' => $this->resolveForecastCategory($properties['hs_manual_forecast_category']),\n ];\n\n if ($accountId) {\n $data['account_id'] = $accountId;\n }\n\n if ($stage) {\n $data['stage_id'] = $stage->id;\n }\n\n if ($businessProcess) {\n $recordType = $this->getCachedBusinessProcessRecordType($businessProcess);\n if ($recordType) {\n $data['record_type_id'] = $recordType->id;\n }\n }\n\n return $data;\n }\n\n private function getCachedOwnerProfile(string $ownerId): mixed\n {\n $cacheKey = $this->config->getId() . ':' . $ownerId;\n if (array_key_exists($cacheKey, $this->cachedOwnerProfiles)) {\n return $this->cachedOwnerProfiles[$cacheKey];\n }\n\n $profile = $this->crmEntityRepository->findProfileByExternalId($this->config, $ownerId);\n $this->cachedOwnerProfiles[$cacheKey] = $profile;\n\n return $profile;\n }\n\n private function getCachedBusinessProcessRecordType(BusinessProcess $businessProcess): mixed\n {\n $cacheKey = $this->config->getId() . ':' . $businessProcess->getId();\n if (array_key_exists($cacheKey, $this->cachedRecordTypes)) {\n return $this->cachedRecordTypes[$cacheKey];\n }\n\n $recordType = $this->crmEntityRepository->getBusinessProcessRecordType($businessProcess);\n $this->cachedRecordTypes[$cacheKey] = $recordType;\n\n return $recordType;\n }\n\n private function resolveBusinessProcess(?string $pipelineId): ?BusinessProcess\n {\n if ($pipelineId === null) {\n return null;\n }\n\n $cacheKey = $this->getBusinessProcessCacheKey($pipelineId);\n if (isset($this->cachedBusinessProcesses[$cacheKey])) {\n return $this->cachedBusinessProcesses[$cacheKey];\n }\n\n $businessProcess = $this->getBusinessProcess($pipelineId);\n\n if (! $businessProcess instanceof BusinessProcess) {\n $this->importStages();\n $businessProcess = $this->getBusinessProcess($pipelineId);\n }\n\n if (! $businessProcess instanceof BusinessProcess) {\n $this->logger->info(\n '[HubSpot] Deal is not attached to a pipeline',\n [\n 'pipeline' => $pipelineId]\n );\n }\n\n $this->cachedBusinessProcesses[$cacheKey] = $businessProcess;\n\n return $businessProcess;\n }\n\n private function getBusinessProcess(string $pipelineId): ?BusinessProcess\n {\n return $this->crmEntityRepository->findBusinessProcessesByExternalId($this->config, $pipelineId);\n }\n\n private function getBusinessProcessCacheKey(string $pipelineId): string\n {\n return $this->config->getId() . '_' . $pipelineId;\n }\n\n private function resolveStage(BusinessProcess $businessProcess, ?string $stageId): ?Stage\n {\n if (empty($stageId)) {\n return null;\n }\n\n $cacheKey = $this->config->getId() . ':' . $businessProcess->getId() . ':' . $stageId;\n if (isset($this->cachedStages[$cacheKey])) {\n return $this->cachedStages[$cacheKey];\n }\n\n $stage = $this->crmEntityRepository->getPipelineStageByConditions(\n $businessProcess,\n [\n 'crm_provider_id' => $stageId,\n 'type' => Stage::TYPE_OPPORTUNITY,\n ]\n );\n\n if ($stage === null) {\n $this->importStages(null, $stageId);\n }\n\n if ($stage === null) {\n $this->logger->info('[HubSpot] Stage does not exist => ' . $stageId);\n }\n\n $this->cachedStages[$cacheKey] = $stage;\n\n return $stage;\n }\n\n private function resolveAmount(array $properties): ?string\n {\n $amount = null;\n if (! empty($properties['amount'])) {\n $amount = str_replace(',', '', $properties['amount']);\n }\n\n if ($this->config->hasDefaultCurrencyFieldSet()) {\n $valueFieldName = $this->config->getDefaultCurrencyField()->getCrmProviderId();\n $amount = $properties[$valueFieldName] ?? $amount;\n }\n\n return $amount;\n }\n\n private function parseCleanDatetime(string $datetime): ?Carbon\n {\n // Treat pre-1980 values as invalid\n $minValidDate = Carbon::parse('1980-01-01 00:00:00');\n\n try {\n $date = Carbon::parse($datetime);\n\n if ($minValidDate->gt($date)) {\n return null;\n }\n\n return $date;\n } catch (Exception) {\n return null; // On parse error, treat as null\n }\n }\n\n private function resolveDealProbability(?string $stageProbability): int\n {\n if ($stageProbability === null) {\n return 0;\n }\n\n $probability = (float) $stageProbability;\n\n return $probability > 1 ? 0 : (int) ($probability * 100);\n }\n\n private function resolveForecastCategory(?string $forecastCategory): string\n {\n if (! $forecastCategory) {\n return Forecast::FORECAST_CATEGORY_UNCATEGORIZED;\n }\n\n $forecastCategory = str_replace('_', ' ', $forecastCategory);\n\n return ucwords(strtolower($forecastCategory));\n }\n\n private function importExternalFieldData(array $properties, int $opportunityId): void\n {\n $this->importOpportunityCrmFieldData(\n $properties,\n $this->getCachedOpportunitySyncableFields(),\n $opportunityId\n );\n }\n\n private function getCachedOpportunitySyncableFields(): array\n {\n $cacheKey = (string) $this->config->getId();\n if (! isset($this->cachedOpportunitySyncableFields[$cacheKey])) {\n $this->cachedOpportunitySyncableFields[$cacheKey] = $this->getOpportunitySyncableFields();\n }\n\n return $this->cachedOpportunitySyncableFields[$cacheKey];\n }\n\n private function importOpportunityContacts(Opportunity $opportunity, array $associations): void\n {\n // Handle empty or missing contact associations\n if (empty($associations)) {\n // Remove all existing contact associations if none provided\n $this->removeAllOpportunityContacts($opportunity);\n\n return;\n }\n\n // Use differential sync approach for better performance and accuracy\n $this->syncOpportunityContactsDifferential($opportunity, $associations);\n }\n\n /**\n * Sync opportunity contacts using differential approach\n * This compares current vs new associations and only makes necessary changes\n */\n private function syncOpportunityContactsDifferential(Opportunity $opportunity, array $contactAssociations): void\n {\n $currentContactCrmIds = $this->getCurrentContactCrmIds($opportunity);\n $contactAssociationIds = array_keys($contactAssociations);\n\n $contactsToAdd = array_diff($contactAssociationIds, $currentContactCrmIds);\n $contactsToRemove = array_diff($currentContactCrmIds, $contactAssociationIds);\n\n if (empty($contactsToAdd) && empty($contactsToRemove)) {\n return;\n }\n\n $this->logContactAssociationChanges($opportunity, $currentContactCrmIds, $contactAssociations, $contactsToAdd, $contactsToRemove);\n\n $this->removeContactAssociations($opportunity, $contactsToRemove);\n $this->addContactAssociations($opportunity, $contactsToAdd, $contactAssociations);\n }\n\n private function getCurrentContactCrmIds(Opportunity $opportunity): array\n {\n return $opportunity->contacts()\n ->pluck('contacts.crm_provider_id')\n ->toArray();\n }\n\n private function logContactAssociationChanges(\n Opportunity $opportunity,\n array $currentContactCrmIds,\n array $contactAssociations,\n array $contactsToAdd,\n array $contactsToRemove\n ): void {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact association changes', [\n 'opportunity_id' => $opportunity->getId(),\n 'current_contacts' => $currentContactCrmIds,\n 'new_contacts' => $contactAssociations,\n 'contacts_to_add' => $contactsToAdd,\n 'contacts_to_remove' => $contactsToRemove,\n ]);\n }\n\n private function removeContactAssociations(Opportunity $opportunity, array $contactsToRemove): void\n {\n if (empty($contactsToRemove)) {\n return;\n }\n\n $contactsToDetach = $opportunity->contacts()\n ->whereIn('contacts.crm_provider_id', $contactsToRemove)\n ->pluck('contacts.id')\n ->toArray();\n\n if (! empty($contactsToDetach)) {\n $opportunity->contacts()->detach($contactsToDetach);\n\n $this->logger->info('[' . $this->getDisplayName() . '] Removed contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'removed_contact_crm_ids' => $contactsToRemove,\n 'removed_contact_count' => count($contactsToDetach),\n ]);\n }\n }\n\n private function addContactAssociations(Opportunity $opportunity, array $contactsToAdd, array $contactAssociations): void\n {\n if (empty($contactsToAdd)) {\n return;\n }\n\n $contactsAdded = [];\n foreach ($contactsToAdd as $crmId) {\n $id = $contactAssociations[$crmId];\n\n if ($this->attachSingleContact($opportunity, (string) $crmId, $id)) {\n $contactsAdded[] = $crmId;\n }\n }\n\n $this->logAddedContacts($opportunity, $contactsAdded);\n }\n\n private function attachSingleContact(Opportunity $opportunity, string $crmId, int $id): bool\n {\n try {\n return $this->performContactAttachment($opportunity, $id, $crmId);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to add contact association', [\n 'opportunity_id' => $opportunity->getId(),\n 'contact_crm_id' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n private function performContactAttachment(Opportunity $opportunity, int $contactId, string $crmId): bool\n {\n try {\n $opportunity->contacts()->attach($contactId, [\n 'crm_provider_id' => $crmId,\n ]);\n\n return true;\n } catch (\\Illuminate\\Database\\QueryException $e) {\n if (str_contains($e->getMessage(), 'Duplicate entry')) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact association already exists', [\n 'contact_id' => $contactId,\n 'contact_crm_id' => $crmId,\n 'opportunity_id' => $opportunity->getId(),\n ]);\n\n return false;\n }\n\n throw $e;\n }\n }\n\n private function logAddedContacts(Opportunity $opportunity, array $contactsAdded): void\n {\n if (! empty($contactsAdded)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Added contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'added_contact_crm_ids' => $contactsAdded,\n 'added_contacts_count' => count($contactsAdded),\n ]);\n }\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}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3637
|
133
|
7
|
2026-05-07T12:32:13.766583+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157133766_m1.jpg...
|
PhpStorm
|
faVsco.js – OpportunitySyncTrait.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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
[{"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":"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":"Hubspot","depth":4,"on_screen":true,"value":"Hubspot","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":"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":"AXButton","text":"Previous Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Next Occurrence","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search All","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Backward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Search Forward","depth":4,"on_screen":true,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Match сase","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Words","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXCheckBox","text":"Regex","depth":4,"on_screen":true,"role_description":"checkbox","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXLink","text":"?","depth":4,"on_screen":true,"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":"AXTextArea","text":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}","depth":4,"on_screen":true,"value":"[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"d4ce87a9-6ca5-4efe-99b3-4220893270d0\",\"trace_id\":\"724e8238-2ed5-4089-9509-9c7c12a3c373\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28: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\":\"172d1ae8-b8cc-4804-bed9-e32d074e265c\",\"trace_id\":\"4817cdef-8d3e-4914-8bee-feffb18efe1b\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"refreshToken\":\"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring start {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.NOTICE: Monitoring end {\"correlation_id\":\"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5\",\"trace_id\":\"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {\"socialAccountId\":1499,\"provider\":\"hubspot\",\"state\":\"connected\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {\"crm_id\":\"374720564\",\"reason\":\"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n\"} {\"correlation_id\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)\n {\"exception\":\"[object] (HubSpot\\\\Client\\\\Crm\\\\Deals\\\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:\n{\\\"status\\\":\\\"error\\\",\\\"message\\\":\\\"You have reached your ten_secondly_rolling limit.\\\",\\\"errorType\\\":\\\"RATE_LIMIT\\\",\\\"correlationId\\\" (truncated...)\n at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)\n[stacktrace]\n#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)\n#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\\\Client\\\\Crm\\\\Deals\\\\Api\\\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')\n#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Client->getOpportunityById('374720564', Array)\n#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\\\Services\\\\Crm\\\\Hubspot\\\\Service->syncOpportunity('374720564')\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\":\"273355f2-6315-4b20-bc9a-c26c681d6344\",\"trace_id\":\"5ea79a26-c838-48e8-9913-93ad508146a6\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28: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\":\"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d\",\"trace_id\":\"1ea62b83-9639-41e3-a523-26404c39fa80\"}\n[2026-05-07 12:28:24] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"mailbox:batch:process\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:24] 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\":\"d191d5c6-133f-43e1-8ed4-d285d0c768b8\",\"trace_id\":\"67798138-bdb7-4bd7-8b32-377663219a88\"}\n[2026-05-07 12:28:27] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {\"correlation_id\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:27] 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\":\"a4e5e18f-9f8c-4196-ace0-bf664d4827d9\",\"trace_id\":\"d75cb10b-4c76-4c00-84d4-26efeb738e17\"}\n[2026-05-07 12:28:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"calendar:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:30] 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\":\"3789f06a-4f0c-4b12-be80-d6a36e089d1b\",\"trace_id\":\"6ce89147-1624-456d-9e75-f4948f2c5db8\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1393,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1393,\"provider\":\"google\",\"refreshToken\":\"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1393,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1387,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1387,\"provider\":\"google\",\"refreshToken\":\"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1387,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1348,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1348,\"provider\":\"google\",\"refreshToken\":\"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1348,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1361,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1361,\"provider\":\"google\",\"refreshToken\":\"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1361,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1310,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1310,\"provider\":\"google\",\"refreshToken\":\"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1310,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1333,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1333,\"provider\":\"google\",\"refreshToken\":\"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1333,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1368,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1368,\"provider\":\"google\",\"refreshToken\":\"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1368,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1365,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1365,\"provider\":\"google\",\"refreshToken\":\"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1365,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1364,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1364,\"provider\":\"google\",\"refreshToken\":\"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1364,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1370,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1370,\"provider\":\"office\",\"refreshToken\":\"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:33Z\\\",\\\"trace_id\\\":\\\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\\\",\\\"correlation_id\\\":\\\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1370,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1202,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1202,\"provider\":\"office\",\"refreshToken\":\"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:34Z\\\",\\\"trace_id\\\":\\\"2a3e5b60-5770-46f2-aca6-7b0527363000\\\",\\\"correlation_id\\\":\\\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1202,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {\"calendar_id\":501} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1300,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1300,\"provider\":\"google\",\"refreshToken\":\"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Account has been deleted\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1300,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1409,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1409,\"provider\":\"google\",\"refreshToken\":\"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1409,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1352,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1352,\"provider\":\"google\",\"refreshToken\":\"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"responseBody\":{\"error\":\"unauthorized_client\",\"error_description\":\"Unauthorized\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1352,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1296,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1296,\"provider\":\"office\",\"refreshToken\":\"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"integration-app\",\"crm_owner\":1695,\"team_id\":3143} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1502,\"provider\":\"google\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:35Z\\\",\\\"trace_id\\\":\\\"2e34e335-a76d-40e5-bc50-3861392e4c00\\\",\\\"correlation_id\\\":\\\"9db5b389-6165-4feb-8e6e-bedc369e1c87\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1296,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":391,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":391,\"provider\":\"office\",\"refreshToken\":\"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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\":\"3015918c-9edf-487d-b1d0-97c9d00ea6b1\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:36Z\\\",\\\"trace_id\\\":\\\"6eba7173-b781-4e55-b1fb-1087ed023000\\\",\\\"correlation_id\\\":\\\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":391,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1271,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1271,\"provider\":\"office\",\"refreshToken\":\"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] 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: b18cbf88-c6d0-4caa-9af9-d2dabb673500 Correlation ID: ead4f7c0-3077-42bb-84d0-c3b9a1432182 Timestamp: 2026-05-07 12:28:37Z\\\",\\\"error_codes\\\":[7000215],\\\"timestamp\\\":\\\"2026-05-07 12:28:37Z\\\",\\\"trace_id\\\":\\\"b18cbf88-c6d0-4caa-9af9-d2dabb673500\\\",\\\"correlation_id\\\":\\\"ead4f7c0-3077-42bb-84d0-c3b9a1432182\\\",\\\"error_uri\\\":\\\"https://login.microsoftonline.com/error?code=7000215\\\"}\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1271,\"provider\":\"office\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1351,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1351,\"provider\":\"google\",\"refreshToken\":\"4271d15b9e60a606439caddc68337f783e472c85b03dacff14d1b6dfded9051c\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1351,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {\"socialAccountId\":1366,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1366,\"provider\":\"google\",\"refreshToken\":\"ae21385059b2eebfd43f68aecd56eccd702a1aabb6598f1f7ab594ed8af491b4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"responseBody\":{\"error\":\"invalid_grant\",\"error_description\":\"Bad Request\"}} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountObserver] Saving model {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.ERROR: [SocialAccountService] Failed to refresh token {\"socialAccountId\":1366,\"provider\":\"google\",\"reason\":\"Flow refresh required.\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":378} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.INFO: Calendar sync job dispatched {\"calendar_id\":504} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] local.NOTICE: Calendar sync end {\"retrieved_calendars\":31,\"processed_calendars\":3} {\"correlation_id\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:38] 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\":\"d543a089-fd32-4522-9ffe-1494e562b741\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"pipedrive\",\"crm_owner\":241,\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"pipedrive\",\"team_id\":19} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1115,\"provider\":\"google\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:40] 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\":\"d023e7ab-3a56-433c-841b-49c58c0cb46d\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1421,\"provider\":\"office\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] 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\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:28:41] local.INFO: [MS Office Calendar] Skipping delta sync for daily mode {\"calendarId\":\"9e8b1a2c-1a8f-42bd-b161-810fc0baf540\"} {\"correlation_id\":\"9ccaf562-7a14-4f4b-8625-81e2bf970988\",\"trace_id\":\"564a362b-7ddb-49f0-a33a-b807b0440231\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:07] 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\":\"0d6b5d8c-5396-45af-b4f1-348978acd054\",\"trace_id\":\"031091b8-40ce-4d57-a4e9-bc4d37034ae0\"}\n[2026-05-07 12:29:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29: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\":\"02cf8f7b-abd2-4e63-87bc-3e8fce928261\",\"trace_id\":\"6752601b-1c03-48ae-a590-323cc5ed601e\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring start {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29:12] local.NOTICE: Monitoring end {\"correlation_id\":\"d3765bc2-52fa-4bc4-9c94-52822e08f7a5\",\"trace_id\":\"0299fb07-ac8c-4159-ad7e-c1bce0958d25\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"d59f6990-3c72-4f1b-b5fa-4035b1be1dbb\",\"trace_id\":\"d502f355-1716-4272-9dc2-79f8c70cbbf4\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:29: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\":\"6e7dd39a-53bc-4359-a50f-7519f217bb9a\",\"trace_id\":\"eef97a11-0a3b-4911-be85-f37bbdc01d15\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"e4a1110b-dccf-46a7-b349-539201c9c258\",\"trace_id\":\"05679e00-ab34-47d6-af74-01a412a269b5\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30: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\":\"3aa037e0-524c-4f99-a2fe-9537e1034e93\",\"trace_id\":\"c8f2c739-13e2-490c-9bce-6b940c4073cc\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring start {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30:12] local.NOTICE: Monitoring end {\"correlation_id\":\"33c6a1f2-608d-47f9-a340-97a81d930e48\",\"trace_id\":\"e07fb9c3-cf43-4caa-bb94-08be684e8e00\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"8da3e1c6-c806-4120-a0d8-8d99e640c4d3\",\"trace_id\":\"4813fc1e-67c7-495d-bafe-1c0bddb52670\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:16] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30: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\":\"a72f5370-11f9-4960-86c6-f91c0f8f3c17\",\"trace_id\":\"c6335d80-1601-41ed-8cbe-bc4a32bca434\"}\n[2026-05-07 12:30:21] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:count\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:28:00, 2026-05-07 12:30:00] {\"correlation_id\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:21] 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\":\"8aae162c-20b5-41f5-9b9a-cc6b832e8802\",\"trace_id\":\"0c29315d-717e-40e7-a21e-4ee0f9ec5ca0\"}\n[2026-05-07 12:30:23] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:purge-stale\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:23] 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\":\"36d2678a-b734-46bd-990e-9968b2fb86d5\",\"trace_id\":\"0f9e0c4b-3fbb-400e-97a8-5b59b1c18d50\"}\n[2026-05-07 12:30:24] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:25] 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\":\"3559116e-0397-44eb-a839-e397bbd4c3f4\",\"trace_id\":\"e765565d-25d2-45ab-b9a4-42ef784a60fc\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] local.INFO: Running pre-meeting notification command {\"correlation_id\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:27] 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\":\"7756bdce-9659-4c40-885e-6cb4097a770a\",\"trace_id\":\"d7767470-3342-4939-845d-800b6e7e0bc9\"}\n[2026-05-07 12:30:28] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:start\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: Running conference:monitor:start command for activities in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] local.INFO: [conference:monitor:start] No activities found in (2026-05-07 12:20:00, 2026-05-07 12:25:00] {\"correlation_id\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:28] 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\":\"3aef2e59-302a-485b-b9ec-20478fd20cf5\",\"trace_id\":\"1dae0aa8-c6fd-4fca-84b2-2bb76ef6721b\"}\n[2026-05-07 12:30:30] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"conference:monitor:end\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesEnded {\"from\":\"12:25\",\"to\":\"12:30\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] local.INFO: conference:monitor:end:Jiminny\\Console\\Commands\\Activities\\MonitorMeetingEndCommand::logActivitiesWithUnfinishedSession {\"from\":\"02:20\",\"to\":\"02:25\"} {\"correlation_id\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:30] 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\":\"46c43768-14e5-4886-b06b-de9c245deaf6\",\"trace_id\":\"4a12fadf-dd6f-4277-bac7-57d6789cbf99\"}\n[2026-05-07 12:30:32] local.NOTICE: Repairing HubSpot tokens start {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":59,\"updated_at\":\"2025-10-03 09:32:05\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":59,\"provider\":\"hubspot\",\"refreshToken\":\"97b78f6e2cc49965c00c2492b602b02708b1392551e6b3f113fbaa48992af90b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: Trying to refresh HubSpot token {\"account_id\":306,\"updated_at\":\"2023-11-27 09:30:03\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:32] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":306,\"provider\":\"hubspot\",\"refreshToken\":\"6fa6aa8cc641d131231acc3470f5c03cb3b07b2e580fb18f8acb3b1dbb72549b\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: Trying to refresh HubSpot token {\"account_id\":1372,\"updated_at\":\"2025-10-02 14:47:06\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.INFO: [SocialAccountService] Refreshing token from provider {\"socialAccountId\":1372,\"provider\":\"hubspot\",\"refreshToken\":\"9aa73948c761da29dce46c177cf9aee1fde483a44169ca38723f9f0597d7a8c4\",\"state\":\"full-refresh\"} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] 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\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:33] local.NOTICE: Repairing HubSpot tokens end {\"total\":3,\"fixed\":0,\"failed\":3} {\"correlation_id\":\"b5827753-349d-4c3e-8315-6edd21487988\",\"trace_id\":\"8f1a0949-4cda-47fd-b4d6-602eb0a03249\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] 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\":\"3fce27e4-1b07-40fc-8a53-fbad08b093e2\",\"trace_id\":\"3b8bc557-6e3e-42bf-853b-b7b38c986086\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Command] Starting polling service {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Service starting {\"memory_limit\":\"256M\",\"max_execution_time\":\"0\",\"initial_memory_mb\":62.0} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Acquired polling lock {\"expires_at\":\"2026-05-07T12:32:37.470385Z\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:37] 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\":\"4b772eb2-f1f8-46d1-afe2-8c7e5bc14182\",\"trace_id\":\"a1b68813-a4cf-4767-8a9f-dde19264b31d\"}\n[2026-05-07 12:30:37] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:39] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:reset-governor\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:39] 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\":\"101dc452-3092-4c93-b585-b80bc8b44698\",\"trace_id\":\"b65e71f7-dad2-4432-9357-c7f05e39ae8f\"}\n[2026-05-07 12:30:42] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"activity:sync\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812319,\"provider\":\"twilio-flex\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812320,\"provider\":\"xant\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812321,\"provider\":\"apollo\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812322,\"provider\":\"groove\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812323,\"provider\":\"twilio-video\",\"team\":\"jiminny\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: Dispatching activity sync job {\"import_id\":812324,\"provider\":\"hubspot\",\"team\":\"hubspot\"} {\"correlation_id\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] 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\":\"5a5ef5ba-0234-42c4-baae-827103cebea9\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:42] local.WARNING: [Salesforce] Account not connected for user {\"userId\":\"cdf8b554-d951-4758-bc2b-c1b85d1cd0b9\",\"account\":null} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"salesforce\",\"crm_owner\":3,\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"salesforce\",\"team_id\":1} {\"correlation_id\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.ALERT: [SyncActivity] Failed {\"import_id\":812319,\"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\":\"f51bdd5f-03c8-4af6-831b-086c01094688\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:42] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812320,\"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\":\"d4e15c5d-717b-4c33-a888-1f98bc199608\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:43] local.ALERT: [SyncActivity] Failed {\"import_id\":812321,\"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\":\"a420fb54-7bc6-4eb3-afc4-c88d457ac2b7\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812322,\"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\":\"3330dbba-b9ee-45de-8c39-b280897cc933\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1173,\"provider\":\"salesforce\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] 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\":\"6c34890d-27f6-452c-918a-d61dfb22dc78\",\"trace_id\":\"2c6a1876-1e2d-4c90-a235-129bfc1fda30\"}\n[2026-05-07 12:30:44] local.ALERT: [SyncActivity] Failed {\"import_id\":812323,\"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\":\"79f1a8bc-6445-4a65-a7e4-a4a2b273f5c4\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":89,\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":408,\"provider\":\"hubspot\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [SyncActivity] Start {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:44] local.INFO: [HubSpot] Search calls for period {\"from\":\"2026-05-07 12:14:00\",\"to\":\"2026-05-07 12:30:00\"} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] End {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:45] local.INFO: [SyncActivity] Memory usage {\"import_id\":812324,\"provider\":\"hubspot\",\"provider_id\":31,\"team\":\"hubspot\",\"team_id\":2,\"memory_usage\":28981120,\"memory_real_usage\":67108864,\"pid\":26154} {\"correlation_id\":\"aebf6b71-0ddc-409f-8ec6-933f9e06059c\",\"trace_id\":\"a71be838-d91c-4f4c-94e8-e34d38d6c0eb\"}\n[2026-05-07 12:30:47] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"crm:bullhorn:ping\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] 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\":\"a3e015c8-7c91-4457-bff4-de94482186fc\",\"trace_id\":\"2966aada-d948-4fec-8388-30f39c48648f\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:47] local.INFO: [HubSpot Journal Auth] Requesting new client credentials token {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Auth] Successfully obtained new access token {\"expires_in\":1800,\"cached_for\":1500} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:30:48] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"nudges:send\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:48] 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\":\"c40e82b8-a5fd-4588-a637-9bd875fc31d9\",\"trace_id\":\"038436d0-e786-4dc4-98f2-f235d5e96a8d\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] starting. {\"playlists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] local.INFO: [Jiminny\\Component\\Playlist\\Command\\NormalizeSortCommand::handle] finished. {\"normalizedPlaylists\":[],\"deletedPlaylists\":[]} {\"correlation_id\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:30:50] 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\":\"5a789fcf-bcf3-433d-8b99-9a04acf54e47\",\"trace_id\":\"b95235c3-8ded-488f-bb53-fe81a3bbe5a1\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:03] 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\":\"15703b0e-3148-4521-97b0-119f62d4bf9a\",\"trace_id\":\"92237a7f-8aae-4d5d-9f0d-b21fb9f33c04\"}\n[2026-05-07 12:31:06] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:06] 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\":\"8970c115-8149-440f-9afd-94a6f7890ed9\",\"trace_id\":\"fef587d7-b0e8-48f0-85b9-b224f5bdbecc\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring start {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31:08] local.NOTICE: Monitoring end {\"correlation_id\":\"8d299958-4bdf-4f50-a904-b3f63d3b6edf\",\"trace_id\":\"8ac0c53d-8ecc-4e29-a465-ff8af18b3565\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"d384715e-b7f3-4ebd-be32-f9c6c9683c6a\",\"trace_id\":\"7221d562-a73d-4a09-8f67-a096ad834b43\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] STARTING batch process {\"host\":\"docker_lamp_1\"} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:12] local.INFO: [EmailSchedule] FINISHED batch process {\"host\":\"docker_lamp_1\",\"processed\":0} {\"correlation_id\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31: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\":\"6b5409ea-62f5-44c3-b853-845c2b06c164\",\"trace_id\":\"3aef745f-0a16-4db4-92d7-b4c04316fcd4\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"daa2a14e-13d8-4e03-ade8-5cf235aff8af\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"usage\":25525984,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] 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\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":109,\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":29} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2b115eb-93ce-4d1b-929c-173757df8fba\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":68.42,\"usage\":25519152,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Your HubSpot account has become disconnected. Please login to Jiminny to reconnect.\"} {\"correlation_id\":\"ceb90517-afd6-4f70-994b-f791459cbe9f\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"usage\":25558232,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Fetching token {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [SocialAccountService] Token retrieved {\"socialAccountId\":1499,\"provider\":\"hubspot\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [EncryptedTokenManager] Generating access token. {\"mode\":\"legacy\"} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {\"crm_provider\":\"hubspot\",\"crm_owner\":148,\"team_id\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:14] local.INFO: [HubSpot] Syncing opportunities using strategy: lastModified {\"team\":2} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [Hubspot] Pagination completed {\"team_id\":2,\"endpoint\":\"https://api.hubapi.com/crm/v3/objects/deals/search\",\"total_requests\":1,\"total_records_fetched\":0,\"total_elapsed_seconds\":0.49,\"average_seconds_per_request\":0.49} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [HubSpot] Synced opportunities {\"team\":2,\"strategies\":\"lastModified\",\"sync_count\":0,\"total\":0,\"last_synced_id\":null,\"duration_ms\":495.28} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"abae74b8-bfa8-4383-9a7f-89f4bf2bdbb4\",\"provider\":\"hubspot\",\"status\":\"completed\",\"duration_ms\":516.14,\"usage\":25681432,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"253d7263-dfb3-42f8-b025-93453379f3ac\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"usage\":25659360,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"2ac0447f-3c8c-4ce0-baeb-b63ddb76fa9b\",\"account\":null} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":130,\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":42} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"b2d49a54-b645-4637-a7ae-a86cfce6e8e4\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":21.43,\"usage\":25505056,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"79c64d03-4641-4366-9691-5b24a4e860b3\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Starting sync {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"usage\":25543424,\"real_usage\":65011712,\"pid\":26151} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.WARNING: [HubSpot] Account not connected for user {\"userId\":\"71e3aac5-fb66-47c5-a236-2d051ae3e319\",\"account\":null} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] Integration owner is not connected, attempting team members {\"crm_provider\":\"hubspot\",\"crm_owner\":256,\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team members found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [CrmOwnerResolver] No team member found with active crm connection {\"crm_provider\":\"hubspot\",\"team_id\":49} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:15] local.INFO: [SyncHubspotObjects] Sync finished {\"team\":\"c6b9d6b0-b48d-4832-a68c-a57d60651888\",\"provider\":\"hubspot\",\"status\":\"disconnected\",\"duration_ms\":15.8,\"usage\":25498888,\"real_usage\":65011712,\"pid\":26151,\"reason\":\"Social account for HubSpot cannot be found. Please login to Jiminny to connect.\"} {\"correlation_id\":\"69f05987-da80-4ff2-8ace-9b4bffb3b7f7\",\"trace_id\":\"296f7872-e07a-4834-87f8-0c4d5594054d\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Getting offset from database {\"offset\":\"\",\"jiminny_team_id\":1} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal API] Fetching latest journal entry {\"url\":\"https://api.hubapi.com/webhooks/v4/journal/latest\"} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] No data {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.WARNING: [HubSpot Journal Polling] Maximum empty results reached, stopping {\"empty_results\":5,\"max_empty_results\":5} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] 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\":218.1,\"avg_download_ms\":0.0,\"avg_transform_ms\":0.0,\"avg_process_ms\":0.0,\"peak_memory_mb\":99.73} {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:31:33] local.INFO: [HubSpot Journal Polling] Released polling lock {\"correlation_id\":\"bee413d5-e5f8-4384-b691-e30383fcd178\",\"trace_id\":\"0da49d98-27ef-441d-8fd8-465c8dc6d31c\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:05] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {\"correlation_id\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32: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\":\"0e01e875-d2c2-41d3-956d-223b1e90dd29\",\"trace_id\":\"bbf4347e-5969-439e-a725-467084a07e73\"}\n[2026-05-07 12:32:09] local.INFO: Jiminny\\Console\\Commands\\Command::run Memory usage before starting command {\"command\":\"dialers:monitor-activities\",\"memoryBeforeCommandInMb\":62.0,\"memoryPeakBeforeCommandInMb\":99.727} {\"correlation_id\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}\n[2026-05-07 12:32: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\":\"99620b99-af26-48c8-9376-70139e107fd6\",\"trace_id\":\"7da3af1b-da2d-4610-b72c-3aabcf9b27a7\"}","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":"32","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"2","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"23","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\\ServiceTraits;\n\nuse Carbon\\Carbon;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\CollectionResponseAssociatedId;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Models\\Account;\nuse Exception;\nuse Jiminny\\Component\\DealInsights\\Forecast\\Forecast;\nuse Jiminny\\Jobs\\Crm\\MatchActivitiesToNewOpportunity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Models\\Opportunity;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\DealFieldsService;\nuse Jiminny\\Services\\Crm\\Hubspot\\OpportunitySyncStrategy\\HubspotSingleSyncStrategy;\nuse Jiminny\\Services\\Crm\\Hubspot\\WebhookSyncBatchProcessor;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Utils\\CurrencyFormatter;\n\n/**\n * Optimized sync methods for better performance\n * These methods can be integrated into SyncCrmEntitiesTrait for significant performance gains\n */\ntrait OpportunitySyncTrait\n{\n private const int BATCH_SIZE = 100;\n private const int BATCH_PROCESS_SIZE = 800;\n\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected DealFieldsService $dealFieldsService;\n\n private ?array $cachedClosedDealStages = null;\n private array $cachedBusinessProcesses = [];\n private array $cachedStages = [];\n /** @var array<string, array<string>> keyed by config id */\n private array $cachedOpportunitySyncableFields = [];\n /** @var array<string, mixed> keyed by configId:ownerId */\n private array $cachedOwnerProfiles = [];\n /** @var array<string, mixed> keyed by configId:businessProcessId */\n private array $cachedRecordTypes = [];\n\n public function syncOpportunities(array $parameters, ?string $strategy = null): int\n {\n $startTime = microtime(true);\n $strategies = $this->opportunitySyncStrategyResolver->getStrategies($this->config, $strategy);\n $parameters['config'] = $this->config;\n $syncCount = 0;\n $reportedTotal = 0;\n $lastSyncedId = [];\n $strategyNames = [];\n\n try {\n foreach ($strategies as $strategyName => $syncStrategy) {\n $strategyNames[] = $strategyName;\n $this->logger->info(\n '[' . $this->getDisplayName() . '] Syncing opportunities using strategy: ' . $strategyName,\n ['team' => $this->team->getId()]\n );\n\n $total = 0;\n $lastId = null;\n $buffer = [];\n\n // HubspotWebhookBatchSyncStrategy returns empty generator, this is for other strategies\n foreach ($syncStrategy->fetchOpportunities($parameters, $total, $lastId) as $hsOpportunity) {\n $buffer[] = $hsOpportunity;\n\n // process every 800 rows (fits < 1 000 association limit)\n if (\\count($buffer) >= self::BATCH_PROCESS_SIZE) {\n $syncCount += $this->processOpportunityBatch($buffer);\n $buffer = [];\n }\n }\n\n // leftovers\n if ($buffer) {\n $syncCount += $this->processOpportunityBatch($buffer);\n }\n\n $reportedTotal += $total;\n $lastSyncedId = $lastId;\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException | CrmException $e) {\n $this->handleSyncException($e, $parameters);\n }\n\n $durationMs = round((microtime(true) - $startTime) * 1000, 2);\n $this->logger->info(\n '[HubSpot] Synced opportunities',\n [\n 'team' => $this->team->getId(),\n 'strategies' => implode(',', $strategyNames),\n 'sync_count' => $syncCount,\n 'total' => $reportedTotal,\n 'last_synced_id' => $lastSyncedId,\n 'duration_ms' => $durationMs,\n ]\n );\n\n return $reportedTotal;\n }\n\n private function handleSyncException(\\Throwable $e, array $parameters): void\n {\n if (($parameters['since'] ?? null) instanceof Carbon) {\n $parameters['since'] = $parameters['since']->toDateTimeString();\n }\n $parameters['config'] = $this->config->getId();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Sync opportunities failed', [\n 'teamId' => $this->team->getUuid(),\n 'parameters' => $parameters,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n /**\n * @inheritdoc\n */\n public function syncOpportunity(string $crmId): ?Opportunity\n {\n $this->client->getOpportunityById($crmId, ['hs_object_id', 'dealname']);\n return null;\n $strategy = $this->opportunitySyncStrategyResolver->resolve(\n $this->config,\n OpportunitySyncStrategyResolver::SINGLE_SYNC_OPPORTUNITY_STRATEGY,\n );\n\n $parameters = [\n 'config' => $this->config,\n 'crm_id' => $crmId,\n ];\n\n try {\n if (! $strategy instanceof HubspotSingleSyncStrategy) {\n throw new InvalidArgumentException('Strategy must by HubspotSingleSyncStrategy');\n }\n\n $hsOpportunity = $strategy->fetchOpportunity($parameters);\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Opportunity not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n $hsOpportunity['associations'] = $this->convertDealAssociations($hsOpportunity['associations'] ?? []);\n\n return $this->importOrUpdateOpportunity($hsOpportunity);\n }\n\n /**\n * Process webhook-collected opportunity batches.\n *\n * Drains Redis sets containing company CRM IDs collected from webhook events\n * and dispatches ImportOpportunityBatch jobs for batch processing.\n *\n * @return int Number of opportunity IDs dispatched to jobs\n */\n public function batchSyncOpportunities(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_DEAL,\n $configId\n );\n }\n\n /**\n * Import a batch of opportunities by their CRM IDs.\n * Fetches opportunity data from HubSpot API and delegates to importOpportunityBatch().\n *\n * @param array<string> $crmIds HubSpot deal CRM IDs\n *\n * @return array{success: array, failed_ids: array, errors?: array<string, string>}\n */\n public function importOpportunityBatchByIds(array $crmIds): array\n {\n $fields = $this->dealFieldsService->getFieldsForConfiguration($this->config);\n\n $allDeals = [];\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n $deals = $this->client->getOpportunitiesByIds($chunk, $fields);\n foreach ($deals as $deal) {\n $allDeals[] = $deal;\n }\n }\n\n // IDs not returned by HubSpot are likely deleted or inaccessible deals.\n // These are not failures — retrying won't bring them back.\n $fetchedIds = array_map('strval', array_column($allDeals, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] CRM IDs not found in HubSpot (likely deleted)', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allDeals),\n ]);\n }\n\n if (empty($allDeals)) {\n return ['success' => [], 'failed_ids' => []];\n }\n\n return $this->importOpportunityBatch($allDeals);\n }\n\n private function getClosedDealStages(): array\n {\n if ($this->cachedClosedDealStages !== null) {\n return $this->cachedClosedDealStages;\n }\n\n $stages = $this->crmEntityRepository->getOpportunityClosedStages($this->config);\n $data = [\n 'lost' => [],\n 'won' => [],\n ];\n\n foreach ($stages as $stage) {\n if ($stage->probability == 0.00) {\n $data['lost'][] = $stage->crm_provider_id;\n }\n if ($stage->probability == 100.00) {\n $data['won'][] = $stage->crm_provider_id;\n }\n }\n\n $this->cachedClosedDealStages = $data;\n\n return $data;\n }\n\n /**\n * Import deals into the database with pre-fetched associations.\n *\n * API calls here (getAssociationsData, getExistingOpportunityCrmIds) are NOT\n * caught — if they throw, the exception propagates to ImportOpportunityBatch::handle()\n * where Laravel retries the whole job with backoff. After all retries exhausted,\n * failed() requeues all IDs to Redis.\n *\n * The per-deal loop catches exceptions individually. A deal can end up in three states:\n * - success: imported/updated successfully\n * - failed_ids: exception thrown (DB constraint violation, corrupt data, etc.)\n * These are permanent issues — retrying won't fix them.\n * - skipped (null): missing dependencies (no account, unknown pipeline/stage).\n * This is acceptable — the deal cannot be imported until those exist.\n */\n private function importOpportunityBatch(array $deals): array\n {\n $syncedOpportunities = [\n 'success' => [],\n 'failed_ids' => [],\n ];\n $dealIds = array_column($deals, 'id');\n $batchStart = microtime(true);\n $slowDeals = [];\n\n // Shared association/existing-ID preparation is batch-level state. If it fails, rethrow so the\n // queue job retries the whole batch and eventually requeues all deal IDs back to Redis.\n try {\n $companyAssocStart = microtime(true);\n $companyAssociations = $this->client->getAssociationsData($dealIds, 'deals', 'companies');\n $companyAssocMs = (int) round((microtime(true) - $companyAssocStart) * 1000);\n\n $contactAssocStart = microtime(true);\n $contactAssociations = $this->client->getAssociationsData($dealIds, 'deals', 'contacts');\n $contactAssocMs = (int) round((microtime(true) - $contactAssocStart) * 1000);\n\n $prepareStart = microtime(true);\n $allCompanyIds = $this->flattenAssociationIds($companyAssociations);\n $allContactIds = $this->flattenAssociationIds($contactAssociations);\n $prepareTimings = [];\n $associationsData = $this->prepareAssociatedEntities(\n $companyAssociations,\n $contactAssociations,\n $prepareTimings\n );\n $prepareMs = (int) round((microtime(true) - $prepareStart) * 1000);\n\n $missingCompanies = count(array_diff(\n $allCompanyIds,\n array_keys($associationsData['company_id_mappings'] ?? [])\n ));\n $missingContacts = count(array_diff(\n $allContactIds,\n array_keys($associationsData['contact_id_mappings'] ?? [])\n ));\n\n $existingCrmIds = $this->crmEntityRepository->getExistingOpportunityCrmIds(\n $this->config,\n array_map('strval', $dealIds)\n );\n $existingCrmIdSet = array_flip($existingCrmIds);\n } catch (\\Throwable $e) {\n $this->logger->error('[' . $this->getDisplayName() . '] Failed to fetch associations or existing IDs', [\n 'teamId' => $this->team->getId(),\n 'dealCount' => count($dealIds),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n $loopStart = microtime(true);\n foreach ($deals as $deal) {\n $dealStart = microtime(true);\n\n try {\n $deal['associations'] = $this->prepareAssociationsForOpportunity(\n $deal['id'],\n $companyAssociations,\n $contactAssociations,\n $associationsData\n );\n\n $syncedOpportunity = $this->importOrUpdateOpportunity(\n $deal,\n isset($existingCrmIdSet[(string) $deal['id']])\n );\n if ($syncedOpportunity) {\n $syncedOpportunities['success'][] = $syncedOpportunity;\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import opportunity', [\n 'teamId' => $this->team->getId(),\n 'crmId' => $deal['id'],\n 'error' => $e->getMessage(),\n ]);\n $syncedOpportunities['failed_ids'][] = $deal['id'];\n $syncedOpportunities['errors'][$deal['id']] = $e->getMessage();\n }\n\n $dealMs = (int) round((microtime(true) - $dealStart) * 1000);\n if ($dealMs > 1000) {\n $slowDeals[] = ['crmId' => $deal['id'], 'ms' => $dealMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importOpportunityBatch timing', [\n 'teamId' => $this->team->getId(),\n 'deal_count' => count($deals),\n 'total_ms' => $totalMs,\n 'company_assoc_api_ms' => $companyAssocMs,\n 'contact_assoc_api_ms' => $contactAssocMs,\n 'prepare_entities_ms' => $prepareMs,\n 'prepare_accounts_ms' => $prepareTimings['accounts_ms'],\n 'prepare_contacts_ms' => $prepareTimings['contacts_ms'],\n 'total_companies' => count($allCompanyIds),\n 'missing_companies' => $missingCompanies,\n 'total_contacts' => count($allContactIds),\n 'missing_contacts' => $missingContacts,\n 'deals_loop_ms' => $loopMs,\n 'avg_deal_ms' => ! empty($deals) ? (int) round($loopMs / count($deals)) : 0,\n 'slow_deals_count' => count($slowDeals),\n 'slow_deals' => array_slice($slowDeals, 0, 10),\n ]);\n\n return $syncedOpportunities;\n }\n\n /**\n * Prepare associated entities for opportunities with optimized batch processing\n * Returns structured data with CRM ID to DB ID mappings for each opportunity\n */\n private function prepareAssociatedEntities(\n array $companyAssociations,\n array $contactAssociations,\n array &$timings = []\n ): array {\n // Step 1: Collect all unique company and contact IDs from associations\n $allCompanyIds = $this->flattenAssociationIds($companyAssociations);\n $allContactIds = $this->flattenAssociationIds($contactAssociations);\n\n // Step 2: Batch sync missing entities and get CRM ID to DB ID mappings\n $companyIdMappings = [];\n $contactIdMappings = [];\n $accountsMs = 0;\n $contactsMs = 0;\n\n if (! empty($allCompanyIds)) {\n $start = microtime(true);\n $companyIdMappings = $this->prepareAssociatedAccounts($allCompanyIds);\n $accountsMs = (int) round((microtime(true) - $start) * 1000);\n }\n\n if (! empty($allContactIds)) {\n $start = microtime(true);\n $contactIdMappings = $this->prepareAssociatedContacts($allContactIds);\n $contactsMs = (int) round((microtime(true) - $start) * 1000);\n }\n\n $timings = [\n 'accounts_ms' => $accountsMs,\n 'contacts_ms' => $contactsMs,\n ];\n\n return [\n 'company_id_mappings' => $companyIdMappings,\n 'contact_id_mappings' => $contactIdMappings,\n ];\n }\n\n /**\n * Flatten association data to get unique IDs\n */\n private function flattenAssociationIds(array $associations): array\n {\n $ids = [];\n foreach ($associations as $dealAssociations) {\n if (is_array($dealAssociations)) {\n foreach ($dealAssociations as $id) {\n $ids[$id] = true;\n }\n }\n }\n\n return array_keys($ids);\n }\n\n /**\n * Batch sync missing accounts\n */\n private function prepareAssociatedAccounts(array $companyIds): array\n {\n // Find which accounts already exist (lean covering-index lookup)\n $existingAccountsData = $this->crmEntityRepository\n ->getExistingAccountIdsMap($this->config, $companyIds);\n\n $missingCompanyIds = array_diff($companyIds, array_keys($existingAccountsData));\n\n if (empty($missingCompanyIds)) {\n return $existingAccountsData;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing accounts', [\n 'teamId' => $this->team->getUuid(),\n 'total_companies' => count($companyIds),\n 'existing_companies' => count($existingAccountsData),\n 'missing_companies' => count($missingCompanyIds),\n ]);\n\n // we already have limit on opportunity ids count\n // Initialize variable before try block\n $syncedAccountsData = [];\n\n try {\n $syncedAccountsData = $this->batchSyncCrmObjects('companies', $missingCompanyIds);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to sync missing accounts', [\n 'size' => count($missingCompanyIds),\n 'error' => $e->getMessage(),\n ]);\n $syncedAccountsData = [];\n }\n\n return $existingAccountsData + $syncedAccountsData;\n }\n\n /**\n * Prepare associated contacts - find existing and sync missing ones\n * Returns mapping of CRM ID to DB ID\n */\n private function prepareAssociatedContacts(array $contactIds): array\n {\n // Find which contacts already exist (lean covering-index lookup)\n $existingContactsData = $this->crmEntityRepository\n ->getExistingContactIdsMap($this->config, $contactIds);\n\n $missingContactIds = array_diff($contactIds, array_keys($existingContactsData));\n\n if (empty($missingContactIds)) {\n return $existingContactsData;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing contacts', [\n 'teamId' => $this->team->getUuid(),\n 'total_contacts' => count($contactIds),\n 'existing_contacts' => count($existingContactsData),\n 'missing_contacts' => count($missingContactIds),\n ]);\n\n // Sync missing contacts using batch API\n try {\n $syncedContactsData = $this->batchSyncCrmObjects('contacts', $missingContactIds);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to sync missing contacts', [\n 'size' => count($missingContactIds),\n 'error' => $e->getMessage(),\n ]);\n $syncedContactsData = [];\n }\n\n return $existingContactsData + $syncedContactsData;\n }\n\n private function batchSyncCrmObjects(string $objectType, array $crmIds): array\n {\n $syncObjects = [];\n $crmObjectIds = array_values($crmIds);\n\n foreach (array_chunk($crmObjectIds, self::BATCH_SIZE) as $chunk) {\n try {\n $objects = $objectType === 'companies' ?\n $this->client->getCompaniesByIds($chunk, $this->getCompanyFields()) :\n $this->client->getContactsByIds($chunk, $this->getContactFields());\n\n foreach ($objects as $objectId => $objectData) {\n $this->importCrmObject($objectType, (string) $objectId, $objectData, $syncObjects);\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch synced ' . $objectType, [\n 'requested_count' => count($chunk),\n 'synced_count' => count($objects),\n ]);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch ' . $objectType . ' sync failed', [\n 'ids' => $chunk,\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n return $syncObjects;\n }\n\n private function importCrmObject(string $objectType, string $objectId, mixed $objectData, array &$syncObjects): void\n {\n try {\n $object = $objectType === 'companies' ?\n $this->importAccount($objectData) :\n $this->importContact($objectData);\n\n if ($object) {\n $syncObjects[$object->getCrmProviderId()] = $object->getId();\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import batch ' . $objectType, [\n 'id' => $objectId,\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n /**\n * Prepare associations for a single opportunity\n *\n * The return value is an array with the following structure:\n * [\n * 'companies' => [\n * $companyCrmId => $companyId,\n * ...\n * ],\n * 'contacts' => [\n * $contactCrmId => $contactId,\n * ...\n * ],\n * 'account_id' => $accountId,\n * ]\n */\n private function prepareAssociationsForOpportunity(\n string $oppCrmId,\n array $companyAssociations,\n array $contactAssociations,\n array $associationsData\n ): array {\n $associations = [\n 'companies' => [],\n 'contacts' => [],\n 'account_id' => null, // Primary account for opportunity\n ];\n\n $oppCompanyIds = $companyAssociations[$oppCrmId] ?? [];\n foreach ($oppCompanyIds as $companyCrmId) {\n if (isset($associationsData['company_id_mappings'][$companyCrmId])) {\n $associations['companies'][$companyCrmId] = $associationsData['company_id_mappings'][$companyCrmId];\n\n // Set primary account (first company becomes primary account)\n if ($associations['account_id'] === null) {\n $associations['account_id'] = $associationsData['company_id_mappings'][$companyCrmId];\n }\n }\n }\n\n $oppContactIds = $contactAssociations[$oppCrmId] ?? [];\n foreach ($oppContactIds as $contactCrmId) {\n if (isset($associationsData['contact_id_mappings'][$contactCrmId])) {\n $associations['contacts'][$contactCrmId] = $associationsData['contact_id_mappings'][$contactCrmId];\n }\n }\n\n return $associations;\n }\n\n /**\n * Update only associations for an opportunity\n */\n private function updateOpportunityAssociations(Opportunity $opportunity, array $associations): void\n {\n // Update contact associations\n $this->importOpportunityContacts($opportunity, $associations['contacts']);\n\n // Update company (account) associations\n $this->updateOpportunityAccount($opportunity, $associations['account_id']);\n }\n\n /**\n * Remove all contact associations from an opportunity\n */\n private function removeAllOpportunityContacts(Opportunity $opportunity): void\n {\n $currentCount = (int) $opportunity->contacts()->count();\n\n if ($currentCount > 0) {\n $opportunity->contacts()->detach();\n\n $this->logger->info('[' . $this->getDisplayName() . '] Removed all contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'removed_count' => $currentCount,\n ]);\n }\n }\n\n private function updateOpportunityAccount(Opportunity $opportunity, ?int $accountId): void\n {\n if ($accountId === null) {\n // No account ID provided - keep current account\n return;\n }\n\n $currentAccountId = $opportunity->getAccountId();\n\n // Only update if account has changed\n if ($currentAccountId !== $accountId) {\n $opportunity->account_id = $accountId;\n $opportunity->save();\n\n $this->logger->info('[' . $this->getDisplayName() . '] Updated opportunity account association', [\n 'opportunity_id' => $opportunity->getId(),\n 'old_account_id' => $currentAccountId,\n 'new_account_id' => $accountId,\n ]);\n }\n }\n\n /**\n * Find existing opportunities by external IDs (OPTIMIZED VERSION)\n * Uses batch query for better performance\n */\n private function findExistingOpportunities(array $crmIds): Collection\n {\n return $this->crmEntityRepository\n ->findOpportunitiesByExternalIds($this->config, $crmIds);\n }\n\n private function processOpportunityBatch(array $opportunities): int\n {\n $syncedOpportunities = $this->importOpportunityBatch($opportunities);\n\n return count($syncedOpportunities['success'] ?? []);\n }\n\n /**\n * Convert single deal associations from HubSpot format to internal format\n * Handles both HubSpot SDK objects and array formats\n *\n * @param array $opportunityAssociations Raw associations from HubSpot API or pre-processed\n *\n * @return array Processed associations with DB IDs\n */\n private function convertDealAssociations(array $opportunityAssociations): array\n {\n $associations = $this->initializeAssociationsStructure();\n\n if (empty($opportunityAssociations)) {\n return $associations;\n }\n\n $associationIds = $this->extractAssociationIds($opportunityAssociations);\n\n $this->processCompanyAssociations($associationIds, $associations);\n $this->processContactAssociations($associationIds, $associations);\n\n return $associations;\n }\n\n private function initializeAssociationsStructure(): array\n {\n return [\n 'companies' => [],\n 'contacts' => [],\n 'account_id' => null, // Primary account for opportunity\n ];\n }\n\n private function extractAssociationIds(array $opportunityAssociations): array\n {\n $associationIds = [];\n\n foreach ($opportunityAssociations as $type => $associationData) {\n if (! empty($associationData)) {\n $associationIds[$type] = $this->convertSingleDealAssociations($associationData);\n }\n }\n\n return $associationIds;\n }\n\n private function processCompanyAssociations(array $associationIds, array &$associations): void\n {\n if (empty($associationIds['companies'])) {\n return;\n }\n\n $companyId = $associationIds['companies'][0];\n $account = $this->findOrSyncAccount($companyId);\n\n if ($account instanceof Account) {\n $associations['companies'][$companyId] = $account->getId();\n $associations['account_id'] = $account->getId();\n }\n }\n\n private function processContactAssociations(array $associationIds, array &$associations): void\n {\n if (empty($associationIds['contacts'])) {\n return;\n }\n\n foreach ($associationIds['contacts'] as $contactId) {\n $contact = $this->findOrSyncContact($contactId);\n\n if ($contact instanceof Contact) {\n $associations['contacts'][$contactId] = $contact->getId();\n }\n }\n }\n\n private function findOrSyncAccount(string $companyId): ?Account\n {\n $account = $this->crmEntityRepository->findAccountByExternalId($this->config, $companyId);\n\n if (! $account instanceof Account) {\n $account = $this->syncAccount($companyId);\n }\n\n return $account;\n }\n\n private function findOrSyncContact(string $contactId): ?Contact\n {\n $contact = $this->crmEntityRepository->findContactByExternalId($this->config, $contactId);\n\n if (! $contact instanceof Contact) {\n $contact = $this->syncContact($contactId);\n }\n\n return $contact;\n }\n\n private function convertSingleDealAssociations($opportunityAssociations = null): array\n {\n $associationData = [];\n\n if ($opportunityAssociations === null) {\n return $associationData;\n }\n\n // Handle array input (from extractAssociationIds)\n if (is_array($opportunityAssociations)) {\n return $opportunityAssociations;\n }\n\n // Handle CollectionResponseAssociatedId object\n if ($opportunityAssociations instanceof CollectionResponseAssociatedId) {\n foreach ($opportunityAssociations->getResults() as $association) {\n $associationData[] = $association->getId();\n }\n }\n\n return $associationData;\n }\n\n private function importOrUpdateOpportunity($crmData, ?bool $exists = null): ?Opportunity\n {\n if (empty($crmData['properties'])) {\n return null;\n }\n\n $crmId = (string) $crmData['id'];\n $properties = $crmData['properties'];\n $associations = $crmData['associations'] ?? [];\n\n $opportunityExists = $exists ?? (bool) $this->crmEntityRepository->findOpportunityByExternalId(\n $this->config,\n $crmId\n );\n\n if ($opportunityExists) {\n return $this->updateOpportunity($crmId, $properties, $associations);\n }\n\n return $this->createOpportunity($crmId, $properties, $associations);\n }\n\n /**\n * Create new opportunity\n */\n private function createOpportunity(string $crmId, array $properties, array $associations): ?Opportunity\n {\n $accountId = $this->resolveAccountId($associations);\n if (! $accountId) {\n return null;\n }\n\n $businessProcess = $this->resolveBusinessProcess($properties['pipeline'] ?? null);\n if (! $businessProcess) {\n return null;\n }\n\n $stage = $this->resolveStage($businessProcess, $properties['dealstage'] ?? null);\n if (! $stage) {\n return null;\n }\n\n $data = $this->buildOpportunityData($properties, $accountId, $businessProcess, $stage);\n\n $attributes = [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $crmId,\n ];\n\n $values = array_merge($attributes, $data);\n\n $opportunity = $this->crmEntityRepository->upsertOpportunity($attributes, $values);\n\n $this->importExternalFieldData($properties, $opportunity->getId());\n $this->importOpportunityContacts($opportunity, $associations['contacts']);\n\n if ($opportunity->wasRecentlyCreated) {\n MatchActivitiesToNewOpportunity::dispatch($opportunity->getId());\n }\n\n return $opportunity;\n }\n\n /**\n * Update existing opportunity\n */\n private function updateOpportunity(string $crmId, array $properties, array $associations): Opportunity\n {\n $accountId = $this->resolveAccountId($associations);\n $businessProcess = $this->resolveBusinessProcess($properties['pipeline'] ?? null);\n $stage = $businessProcess ? $this->resolveStage($businessProcess, $properties['dealstage'] ?? null) : null;\n\n $data = $this->buildOpportunityData($properties, $accountId, $businessProcess, $stage);\n\n $attributes = [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $crmId,\n ];\n\n $values = array_merge($attributes, $data);\n $opportunity = $this->crmEntityRepository->upsertOpportunity($attributes, $values);\n\n $this->importExternalFieldData($properties, $opportunity->getId());\n $this->updateOpportunityAssociations($opportunity, $associations);\n\n return $opportunity;\n }\n\n private function resolveAccountId(array $associations): ?int\n {\n if (! empty($associations['account_id'])) {\n return $associations['account_id'];\n }\n\n if (empty($associations)) {\n return null;\n }\n\n // Fallback: use first company as account (currently SDK returns one company)\n foreach ($associations['companies'] as $accountId) {\n return $accountId;\n }\n\n return null;\n }\n\n private function buildOpportunityData(\n array $properties,\n ?int $accountId,\n ?BusinessProcess $businessProcess,\n ?Stage $stage\n ): array {\n $ownerId = null;\n $profile = null;\n if (! empty($properties['hubspot_owner_id'])) {\n $ownerId = $properties['hubspot_owner_id'];\n $profile = $this->getCachedOwnerProfile((string) $ownerId);\n }\n\n $name = 'Unknown';\n if (isset($properties['dealname'])) {\n $name = mb_strimwidth($properties['dealname'], 0, 128);\n }\n\n $amount = $this->resolveAmount($properties);\n $currency = $properties['deal_currency_code'] ?? null;\n\n $closeDate = null;\n if (! empty($properties['closedate'])) {\n $closeDate = Carbon::parse($properties['closedate'])->format('Y-m-d');\n }\n\n $remotelyCreatedAt = null;\n if (! empty($properties['createdate']) && strtotime($properties['createdate'])) {\n $date = $this->parseCleanDatetime($properties['createdate']);\n $remotelyCreatedAt = $date?->format('Y-m-d H:i:s');\n }\n\n $closedStages = $this->getClosedDealStages();\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $data = [\n 'team_id' => $this->team->getId(),\n 'user_id' => $profile ? $profile->user_id : null,\n 'owner_id' => $ownerId,\n 'name' => $name,\n 'value' => ! empty($amount) ? $amount : null,\n 'currency_code' => CurrencyFormatter::formatCode($currency),\n 'close_date' => $closeDate,\n 'is_closed' => $isWon || $isLost,\n 'is_won' => $isWon,\n 'remotely_created_at' => $remotelyCreatedAt,\n 'probability' => $this->resolveDealProbability($properties['hs_deal_stage_probability']),\n 'forecast_category' => $this->resolveForecastCategory($properties['hs_manual_forecast_category']),\n ];\n\n if ($accountId) {\n $data['account_id'] = $accountId;\n }\n\n if ($stage) {\n $data['stage_id'] = $stage->id;\n }\n\n if ($businessProcess) {\n $recordType = $this->getCachedBusinessProcessRecordType($businessProcess);\n if ($recordType) {\n $data['record_type_id'] = $recordType->id;\n }\n }\n\n return $data;\n }\n\n private function getCachedOwnerProfile(string $ownerId): mixed\n {\n $cacheKey = $this->config->getId() . ':' . $ownerId;\n if (array_key_exists($cacheKey, $this->cachedOwnerProfiles)) {\n return $this->cachedOwnerProfiles[$cacheKey];\n }\n\n $profile = $this->crmEntityRepository->findProfileByExternalId($this->config, $ownerId);\n $this->cachedOwnerProfiles[$cacheKey] = $profile;\n\n return $profile;\n }\n\n private function getCachedBusinessProcessRecordType(BusinessProcess $businessProcess): mixed\n {\n $cacheKey = $this->config->getId() . ':' . $businessProcess->getId();\n if (array_key_exists($cacheKey, $this->cachedRecordTypes)) {\n return $this->cachedRecordTypes[$cacheKey];\n }\n\n $recordType = $this->crmEntityRepository->getBusinessProcessRecordType($businessProcess);\n $this->cachedRecordTypes[$cacheKey] = $recordType;\n\n return $recordType;\n }\n\n private function resolveBusinessProcess(?string $pipelineId): ?BusinessProcess\n {\n if ($pipelineId === null) {\n return null;\n }\n\n $cacheKey = $this->getBusinessProcessCacheKey($pipelineId);\n if (isset($this->cachedBusinessProcesses[$cacheKey])) {\n return $this->cachedBusinessProcesses[$cacheKey];\n }\n\n $businessProcess = $this->getBusinessProcess($pipelineId);\n\n if (! $businessProcess instanceof BusinessProcess) {\n $this->importStages();\n $businessProcess = $this->getBusinessProcess($pipelineId);\n }\n\n if (! $businessProcess instanceof BusinessProcess) {\n $this->logger->info(\n '[HubSpot] Deal is not attached to a pipeline',\n [\n 'pipeline' => $pipelineId]\n );\n }\n\n $this->cachedBusinessProcesses[$cacheKey] = $businessProcess;\n\n return $businessProcess;\n }\n\n private function getBusinessProcess(string $pipelineId): ?BusinessProcess\n {\n return $this->crmEntityRepository->findBusinessProcessesByExternalId($this->config, $pipelineId);\n }\n\n private function getBusinessProcessCacheKey(string $pipelineId): string\n {\n return $this->config->getId() . '_' . $pipelineId;\n }\n\n private function resolveStage(BusinessProcess $businessProcess, ?string $stageId): ?Stage\n {\n if (empty($stageId)) {\n return null;\n }\n\n $cacheKey = $this->config->getId() . ':' . $businessProcess->getId() . ':' . $stageId;\n if (isset($this->cachedStages[$cacheKey])) {\n return $this->cachedStages[$cacheKey];\n }\n\n $stage = $this->crmEntityRepository->getPipelineStageByConditions(\n $businessProcess,\n [\n 'crm_provider_id' => $stageId,\n 'type' => Stage::TYPE_OPPORTUNITY,\n ]\n );\n\n if ($stage === null) {\n $this->importStages(null, $stageId);\n }\n\n if ($stage === null) {\n $this->logger->info('[HubSpot] Stage does not exist => ' . $stageId);\n }\n\n $this->cachedStages[$cacheKey] = $stage;\n\n return $stage;\n }\n\n private function resolveAmount(array $properties): ?string\n {\n $amount = null;\n if (! empty($properties['amount'])) {\n $amount = str_replace(',', '', $properties['amount']);\n }\n\n if ($this->config->hasDefaultCurrencyFieldSet()) {\n $valueFieldName = $this->config->getDefaultCurrencyField()->getCrmProviderId();\n $amount = $properties[$valueFieldName] ?? $amount;\n }\n\n return $amount;\n }\n\n private function parseCleanDatetime(string $datetime): ?Carbon\n {\n // Treat pre-1980 values as invalid\n $minValidDate = Carbon::parse('1980-01-01 00:00:00');\n\n try {\n $date = Carbon::parse($datetime);\n\n if ($minValidDate->gt($date)) {\n return null;\n }\n\n return $date;\n } catch (Exception) {\n return null; // On parse error, treat as null\n }\n }\n\n private function resolveDealProbability(?string $stageProbability): int\n {\n if ($stageProbability === null) {\n return 0;\n }\n\n $probability = (float) $stageProbability;\n\n return $probability > 1 ? 0 : (int) ($probability * 100);\n }\n\n private function resolveForecastCategory(?string $forecastCategory): string\n {\n if (! $forecastCategory) {\n return Forecast::FORECAST_CATEGORY_UNCATEGORIZED;\n }\n\n $forecastCategory = str_replace('_', ' ', $forecastCategory);\n\n return ucwords(strtolower($forecastCategory));\n }\n\n private function importExternalFieldData(array $properties, int $opportunityId): void\n {\n $this->importOpportunityCrmFieldData(\n $properties,\n $this->getCachedOpportunitySyncableFields(),\n $opportunityId\n );\n }\n\n private function getCachedOpportunitySyncableFields(): array\n {\n $cacheKey = (string) $this->config->getId();\n if (! isset($this->cachedOpportunitySyncableFields[$cacheKey])) {\n $this->cachedOpportunitySyncableFields[$cacheKey] = $this->getOpportunitySyncableFields();\n }\n\n return $this->cachedOpportunitySyncableFields[$cacheKey];\n }\n\n private function importOpportunityContacts(Opportunity $opportunity, array $associations): void\n {\n // Handle empty or missing contact associations\n if (empty($associations)) {\n // Remove all existing contact associations if none provided\n $this->removeAllOpportunityContacts($opportunity);\n\n return;\n }\n\n // Use differential sync approach for better performance and accuracy\n $this->syncOpportunityContactsDifferential($opportunity, $associations);\n }\n\n /**\n * Sync opportunity contacts using differential approach\n * This compares current vs new associations and only makes necessary changes\n */\n private function syncOpportunityContactsDifferential(Opportunity $opportunity, array $contactAssociations): void\n {\n $currentContactCrmIds = $this->getCurrentContactCrmIds($opportunity);\n $contactAssociationIds = array_keys($contactAssociations);\n\n $contactsToAdd = array_diff($contactAssociationIds, $currentContactCrmIds);\n $contactsToRemove = array_diff($currentContactCrmIds, $contactAssociationIds);\n\n if (empty($contactsToAdd) && empty($contactsToRemove)) {\n return;\n }\n\n $this->logContactAssociationChanges($opportunity, $currentContactCrmIds, $contactAssociations, $contactsToAdd, $contactsToRemove);\n\n $this->removeContactAssociations($opportunity, $contactsToRemove);\n $this->addContactAssociations($opportunity, $contactsToAdd, $contactAssociations);\n }\n\n private function getCurrentContactCrmIds(Opportunity $opportunity): array\n {\n return $opportunity->contacts()\n ->pluck('contacts.crm_provider_id')\n ->toArray();\n }\n\n private function logContactAssociationChanges(\n Opportunity $opportunity,\n array $currentContactCrmIds,\n array $contactAssociations,\n array $contactsToAdd,\n array $contactsToRemove\n ): void {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact association changes', [\n 'opportunity_id' => $opportunity->getId(),\n 'current_contacts' => $currentContactCrmIds,\n 'new_contacts' => $contactAssociations,\n 'contacts_to_add' => $contactsToAdd,\n 'contacts_to_remove' => $contactsToRemove,\n ]);\n }\n\n private function removeContactAssociations(Opportunity $opportunity, array $contactsToRemove): void\n {\n if (empty($contactsToRemove)) {\n return;\n }\n\n $contactsToDetach = $opportunity->contacts()\n ->whereIn('contacts.crm_provider_id', $contactsToRemove)\n ->pluck('contacts.id')\n ->toArray();\n\n if (! empty($contactsToDetach)) {\n $opportunity->contacts()->detach($contactsToDetach);\n\n $this->logger->info('[' . $this->getDisplayName() . '] Removed contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'removed_contact_crm_ids' => $contactsToRemove,\n 'removed_contact_count' => count($contactsToDetach),\n ]);\n }\n }\n\n private function addContactAssociations(Opportunity $opportunity, array $contactsToAdd, array $contactAssociations): void\n {\n if (empty($contactsToAdd)) {\n return;\n }\n\n $contactsAdded = [];\n foreach ($contactsToAdd as $crmId) {\n $id = $contactAssociations[$crmId];\n\n if ($this->attachSingleContact($opportunity, (string) $crmId, $id)) {\n $contactsAdded[] = $crmId;\n }\n }\n\n $this->logAddedContacts($opportunity, $contactsAdded);\n }\n\n private function attachSingleContact(Opportunity $opportunity, string $crmId, int $id): bool\n {\n try {\n return $this->performContactAttachment($opportunity, $id, $crmId);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to add contact association', [\n 'opportunity_id' => $opportunity->getId(),\n 'contact_crm_id' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n private function performContactAttachment(Opportunity $opportunity, int $contactId, string $crmId): bool\n {\n try {\n $opportunity->contacts()->attach($contactId, [\n 'crm_provider_id' => $crmId,\n ]);\n\n return true;\n } catch (\\Illuminate\\Database\\QueryException $e) {\n if (str_contains($e->getMessage(), 'Duplicate entry')) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact association already exists', [\n 'contact_id' => $contactId,\n 'contact_crm_id' => $crmId,\n 'opportunity_id' => $opportunity->getId(),\n ]);\n\n return false;\n }\n\n throw $e;\n }\n }\n\n private function logAddedContacts(Opportunity $opportunity, array $contactsAdded): void\n {\n if (! empty($contactsAdded)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Added contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'added_contact_crm_ids' => $contactsAdded,\n 'added_contacts_count' => count($contactsAdded),\n ]);\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Services\\Crm\\Hubspot\\ServiceTraits;\n\nuse Carbon\\Carbon;\nuse HubSpot\\Client\\Crm\\Deals\\Model\\CollectionResponseAssociatedId;\nuse Jiminny\\Exceptions\\InvalidArgumentException;\nuse Jiminny\\Models\\Account;\nuse Exception;\nuse Jiminny\\Component\\DealInsights\\Forecast\\Forecast;\nuse Jiminny\\Jobs\\Crm\\MatchActivitiesToNewOpportunity;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\BusinessProcess;\nuse Jiminny\\Exceptions\\CrmException;\nuse Jiminny\\Models\\Opportunity;\nuse Illuminate\\Support\\Collection;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Repositories\\Crm\\CrmEntityRepository;\nuse Jiminny\\Services\\Crm\\Hubspot\\DealFieldsService;\nuse Jiminny\\Services\\Crm\\Hubspot\\OpportunitySyncStrategy\\HubspotSingleSyncStrategy;\nuse Jiminny\\Services\\Crm\\Hubspot\\WebhookSyncBatchProcessor;\nuse Jiminny\\Services\\Crm\\OpportunitySyncStrategyResolver;\nuse Jiminny\\Utils\\CurrencyFormatter;\n\n/**\n * Optimized sync methods for better performance\n * These methods can be integrated into SyncCrmEntitiesTrait for significant performance gains\n */\ntrait OpportunitySyncTrait\n{\n private const int BATCH_SIZE = 100;\n private const int BATCH_PROCESS_SIZE = 800;\n\n protected OpportunitySyncStrategyResolver $opportunitySyncStrategyResolver;\n protected CrmEntityRepository $crmEntityRepository;\n protected DealFieldsService $dealFieldsService;\n\n private ?array $cachedClosedDealStages = null;\n private array $cachedBusinessProcesses = [];\n private array $cachedStages = [];\n /** @var array<string, array<string>> keyed by config id */\n private array $cachedOpportunitySyncableFields = [];\n /** @var array<string, mixed> keyed by configId:ownerId */\n private array $cachedOwnerProfiles = [];\n /** @var array<string, mixed> keyed by configId:businessProcessId */\n private array $cachedRecordTypes = [];\n\n public function syncOpportunities(array $parameters, ?string $strategy = null): int\n {\n $startTime = microtime(true);\n $strategies = $this->opportunitySyncStrategyResolver->getStrategies($this->config, $strategy);\n $parameters['config'] = $this->config;\n $syncCount = 0;\n $reportedTotal = 0;\n $lastSyncedId = [];\n $strategyNames = [];\n\n try {\n foreach ($strategies as $strategyName => $syncStrategy) {\n $strategyNames[] = $strategyName;\n $this->logger->info(\n '[' . $this->getDisplayName() . '] Syncing opportunities using strategy: ' . $strategyName,\n ['team' => $this->team->getId()]\n );\n\n $total = 0;\n $lastId = null;\n $buffer = [];\n\n // HubspotWebhookBatchSyncStrategy returns empty generator, this is for other strategies\n foreach ($syncStrategy->fetchOpportunities($parameters, $total, $lastId) as $hsOpportunity) {\n $buffer[] = $hsOpportunity;\n\n // process every 800 rows (fits < 1 000 association limit)\n if (\\count($buffer) >= self::BATCH_PROCESS_SIZE) {\n $syncCount += $this->processOpportunityBatch($buffer);\n $buffer = [];\n }\n }\n\n // leftovers\n if ($buffer) {\n $syncCount += $this->processOpportunityBatch($buffer);\n }\n\n $reportedTotal += $total;\n $lastSyncedId = $lastId;\n }\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException | CrmException $e) {\n $this->handleSyncException($e, $parameters);\n }\n\n $durationMs = round((microtime(true) - $startTime) * 1000, 2);\n $this->logger->info(\n '[HubSpot] Synced opportunities',\n [\n 'team' => $this->team->getId(),\n 'strategies' => implode(',', $strategyNames),\n 'sync_count' => $syncCount,\n 'total' => $reportedTotal,\n 'last_synced_id' => $lastSyncedId,\n 'duration_ms' => $durationMs,\n ]\n );\n\n return $reportedTotal;\n }\n\n private function handleSyncException(\\Throwable $e, array $parameters): void\n {\n if (($parameters['since'] ?? null) instanceof Carbon) {\n $parameters['since'] = $parameters['since']->toDateTimeString();\n }\n $parameters['config'] = $this->config->getId();\n\n $this->logger->warning('[' . $this->getDisplayName() . '] Sync opportunities failed', [\n 'teamId' => $this->team->getUuid(),\n 'parameters' => $parameters,\n 'reason' => $e->getMessage(),\n ]);\n }\n\n /**\n * @inheritdoc\n */\n public function syncOpportunity(string $crmId): ?Opportunity\n {\n $this->client->getOpportunityById($crmId, ['hs_object_id', 'dealname']);\n return null;\n $strategy = $this->opportunitySyncStrategyResolver->resolve(\n $this->config,\n OpportunitySyncStrategyResolver::SINGLE_SYNC_OPPORTUNITY_STRATEGY,\n );\n\n $parameters = [\n 'config' => $this->config,\n 'crm_id' => $crmId,\n ];\n\n try {\n if (! $strategy instanceof HubspotSingleSyncStrategy) {\n throw new InvalidArgumentException('Strategy must by HubspotSingleSyncStrategy');\n }\n\n $hsOpportunity = $strategy->fetchOpportunity($parameters);\n } catch (\\HubSpot\\Client\\Crm\\Deals\\ApiException $e) {\n $this->logger->info('[' . $this->getDisplayName() . '] Opportunity not found', [\n 'teamId' => $this->team->getUuid(),\n 'crmId' => $crmId,\n 'reason' => $e->getMessage(),\n ]);\n\n return null;\n }\n\n $hsOpportunity['associations'] = $this->convertDealAssociations($hsOpportunity['associations'] ?? []);\n\n return $this->importOrUpdateOpportunity($hsOpportunity);\n }\n\n /**\n * Process webhook-collected opportunity batches.\n *\n * Drains Redis sets containing company CRM IDs collected from webhook events\n * and dispatches ImportOpportunityBatch jobs for batch processing.\n *\n * @return int Number of opportunity IDs dispatched to jobs\n */\n public function batchSyncOpportunities(): int\n {\n $configId = $this->team->getCrmConfiguration()->getId();\n\n return $this->batchProcessor->processBatchesForObjectType(\n WebhookSyncBatchProcessor::OBJECT_TYPE_DEAL,\n $configId\n );\n }\n\n /**\n * Import a batch of opportunities by their CRM IDs.\n * Fetches opportunity data from HubSpot API and delegates to importOpportunityBatch().\n *\n * @param array<string> $crmIds HubSpot deal CRM IDs\n *\n * @return array{success: array, failed_ids: array, errors?: array<string, string>}\n */\n public function importOpportunityBatchByIds(array $crmIds): array\n {\n $fields = $this->dealFieldsService->getFieldsForConfiguration($this->config);\n\n $allDeals = [];\n foreach (array_chunk($crmIds, self::BATCH_SIZE) as $chunk) {\n $deals = $this->client->getOpportunitiesByIds($chunk, $fields);\n foreach ($deals as $deal) {\n $allDeals[] = $deal;\n }\n }\n\n // IDs not returned by HubSpot are likely deleted or inaccessible deals.\n // These are not failures — retrying won't bring them back.\n $fetchedIds = array_map('strval', array_column($allDeals, 'id'));\n $notFoundIds = array_values(array_diff(array_map('strval', $crmIds), $fetchedIds));\n\n if (! empty($notFoundIds)) {\n $this->logger->info('[' . $this->getDisplayName() . '] CRM IDs not found in HubSpot (likely deleted)', [\n 'teamId' => $this->team->getId(),\n 'notFoundCount' => \\count($notFoundIds),\n 'notFoundIds' => $notFoundIds,\n 'requestedCount' => \\count($crmIds),\n 'fetchedCount' => \\count($allDeals),\n ]);\n }\n\n if (empty($allDeals)) {\n return ['success' => [], 'failed_ids' => []];\n }\n\n return $this->importOpportunityBatch($allDeals);\n }\n\n private function getClosedDealStages(): array\n {\n if ($this->cachedClosedDealStages !== null) {\n return $this->cachedClosedDealStages;\n }\n\n $stages = $this->crmEntityRepository->getOpportunityClosedStages($this->config);\n $data = [\n 'lost' => [],\n 'won' => [],\n ];\n\n foreach ($stages as $stage) {\n if ($stage->probability == 0.00) {\n $data['lost'][] = $stage->crm_provider_id;\n }\n if ($stage->probability == 100.00) {\n $data['won'][] = $stage->crm_provider_id;\n }\n }\n\n $this->cachedClosedDealStages = $data;\n\n return $data;\n }\n\n /**\n * Import deals into the database with pre-fetched associations.\n *\n * API calls here (getAssociationsData, getExistingOpportunityCrmIds) are NOT\n * caught — if they throw, the exception propagates to ImportOpportunityBatch::handle()\n * where Laravel retries the whole job with backoff. After all retries exhausted,\n * failed() requeues all IDs to Redis.\n *\n * The per-deal loop catches exceptions individually. A deal can end up in three states:\n * - success: imported/updated successfully\n * - failed_ids: exception thrown (DB constraint violation, corrupt data, etc.)\n * These are permanent issues — retrying won't fix them.\n * - skipped (null): missing dependencies (no account, unknown pipeline/stage).\n * This is acceptable — the deal cannot be imported until those exist.\n */\n private function importOpportunityBatch(array $deals): array\n {\n $syncedOpportunities = [\n 'success' => [],\n 'failed_ids' => [],\n ];\n $dealIds = array_column($deals, 'id');\n $batchStart = microtime(true);\n $slowDeals = [];\n\n // Shared association/existing-ID preparation is batch-level state. If it fails, rethrow so the\n // queue job retries the whole batch and eventually requeues all deal IDs back to Redis.\n try {\n $companyAssocStart = microtime(true);\n $companyAssociations = $this->client->getAssociationsData($dealIds, 'deals', 'companies');\n $companyAssocMs = (int) round((microtime(true) - $companyAssocStart) * 1000);\n\n $contactAssocStart = microtime(true);\n $contactAssociations = $this->client->getAssociationsData($dealIds, 'deals', 'contacts');\n $contactAssocMs = (int) round((microtime(true) - $contactAssocStart) * 1000);\n\n $prepareStart = microtime(true);\n $allCompanyIds = $this->flattenAssociationIds($companyAssociations);\n $allContactIds = $this->flattenAssociationIds($contactAssociations);\n $prepareTimings = [];\n $associationsData = $this->prepareAssociatedEntities(\n $companyAssociations,\n $contactAssociations,\n $prepareTimings\n );\n $prepareMs = (int) round((microtime(true) - $prepareStart) * 1000);\n\n $missingCompanies = count(array_diff(\n $allCompanyIds,\n array_keys($associationsData['company_id_mappings'] ?? [])\n ));\n $missingContacts = count(array_diff(\n $allContactIds,\n array_keys($associationsData['contact_id_mappings'] ?? [])\n ));\n\n $existingCrmIds = $this->crmEntityRepository->getExistingOpportunityCrmIds(\n $this->config,\n array_map('strval', $dealIds)\n );\n $existingCrmIdSet = array_flip($existingCrmIds);\n } catch (\\Throwable $e) {\n $this->logger->error('[' . $this->getDisplayName() . '] Failed to fetch associations or existing IDs', [\n 'teamId' => $this->team->getId(),\n 'dealCount' => count($dealIds),\n 'error' => $e->getMessage(),\n ]);\n\n throw $e;\n }\n\n $loopStart = microtime(true);\n foreach ($deals as $deal) {\n $dealStart = microtime(true);\n\n try {\n $deal['associations'] = $this->prepareAssociationsForOpportunity(\n $deal['id'],\n $companyAssociations,\n $contactAssociations,\n $associationsData\n );\n\n $syncedOpportunity = $this->importOrUpdateOpportunity(\n $deal,\n isset($existingCrmIdSet[(string) $deal['id']])\n );\n if ($syncedOpportunity) {\n $syncedOpportunities['success'][] = $syncedOpportunity;\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import opportunity', [\n 'teamId' => $this->team->getId(),\n 'crmId' => $deal['id'],\n 'error' => $e->getMessage(),\n ]);\n $syncedOpportunities['failed_ids'][] = $deal['id'];\n $syncedOpportunities['errors'][$deal['id']] = $e->getMessage();\n }\n\n $dealMs = (int) round((microtime(true) - $dealStart) * 1000);\n if ($dealMs > 1000) {\n $slowDeals[] = ['crmId' => $deal['id'], 'ms' => $dealMs];\n }\n }\n $loopMs = (int) round((microtime(true) - $loopStart) * 1000);\n $totalMs = (int) round((microtime(true) - $batchStart) * 1000);\n\n $this->logger->info('[' . $this->getDisplayName() . '] importOpportunityBatch timing', [\n 'teamId' => $this->team->getId(),\n 'deal_count' => count($deals),\n 'total_ms' => $totalMs,\n 'company_assoc_api_ms' => $companyAssocMs,\n 'contact_assoc_api_ms' => $contactAssocMs,\n 'prepare_entities_ms' => $prepareMs,\n 'prepare_accounts_ms' => $prepareTimings['accounts_ms'],\n 'prepare_contacts_ms' => $prepareTimings['contacts_ms'],\n 'total_companies' => count($allCompanyIds),\n 'missing_companies' => $missingCompanies,\n 'total_contacts' => count($allContactIds),\n 'missing_contacts' => $missingContacts,\n 'deals_loop_ms' => $loopMs,\n 'avg_deal_ms' => ! empty($deals) ? (int) round($loopMs / count($deals)) : 0,\n 'slow_deals_count' => count($slowDeals),\n 'slow_deals' => array_slice($slowDeals, 0, 10),\n ]);\n\n return $syncedOpportunities;\n }\n\n /**\n * Prepare associated entities for opportunities with optimized batch processing\n * Returns structured data with CRM ID to DB ID mappings for each opportunity\n */\n private function prepareAssociatedEntities(\n array $companyAssociations,\n array $contactAssociations,\n array &$timings = []\n ): array {\n // Step 1: Collect all unique company and contact IDs from associations\n $allCompanyIds = $this->flattenAssociationIds($companyAssociations);\n $allContactIds = $this->flattenAssociationIds($contactAssociations);\n\n // Step 2: Batch sync missing entities and get CRM ID to DB ID mappings\n $companyIdMappings = [];\n $contactIdMappings = [];\n $accountsMs = 0;\n $contactsMs = 0;\n\n if (! empty($allCompanyIds)) {\n $start = microtime(true);\n $companyIdMappings = $this->prepareAssociatedAccounts($allCompanyIds);\n $accountsMs = (int) round((microtime(true) - $start) * 1000);\n }\n\n if (! empty($allContactIds)) {\n $start = microtime(true);\n $contactIdMappings = $this->prepareAssociatedContacts($allContactIds);\n $contactsMs = (int) round((microtime(true) - $start) * 1000);\n }\n\n $timings = [\n 'accounts_ms' => $accountsMs,\n 'contacts_ms' => $contactsMs,\n ];\n\n return [\n 'company_id_mappings' => $companyIdMappings,\n 'contact_id_mappings' => $contactIdMappings,\n ];\n }\n\n /**\n * Flatten association data to get unique IDs\n */\n private function flattenAssociationIds(array $associations): array\n {\n $ids = [];\n foreach ($associations as $dealAssociations) {\n if (is_array($dealAssociations)) {\n foreach ($dealAssociations as $id) {\n $ids[$id] = true;\n }\n }\n }\n\n return array_keys($ids);\n }\n\n /**\n * Batch sync missing accounts\n */\n private function prepareAssociatedAccounts(array $companyIds): array\n {\n // Find which accounts already exist (lean covering-index lookup)\n $existingAccountsData = $this->crmEntityRepository\n ->getExistingAccountIdsMap($this->config, $companyIds);\n\n $missingCompanyIds = array_diff($companyIds, array_keys($existingAccountsData));\n\n if (empty($missingCompanyIds)) {\n return $existingAccountsData;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing accounts', [\n 'teamId' => $this->team->getUuid(),\n 'total_companies' => count($companyIds),\n 'existing_companies' => count($existingAccountsData),\n 'missing_companies' => count($missingCompanyIds),\n ]);\n\n // we already have limit on opportunity ids count\n // Initialize variable before try block\n $syncedAccountsData = [];\n\n try {\n $syncedAccountsData = $this->batchSyncCrmObjects('companies', $missingCompanyIds);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to sync missing accounts', [\n 'size' => count($missingCompanyIds),\n 'error' => $e->getMessage(),\n ]);\n $syncedAccountsData = [];\n }\n\n return $existingAccountsData + $syncedAccountsData;\n }\n\n /**\n * Prepare associated contacts - find existing and sync missing ones\n * Returns mapping of CRM ID to DB ID\n */\n private function prepareAssociatedContacts(array $contactIds): array\n {\n // Find which contacts already exist (lean covering-index lookup)\n $existingContactsData = $this->crmEntityRepository\n ->getExistingContactIdsMap($this->config, $contactIds);\n\n $missingContactIds = array_diff($contactIds, array_keys($existingContactsData));\n\n if (empty($missingContactIds)) {\n return $existingContactsData;\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch syncing missing contacts', [\n 'teamId' => $this->team->getUuid(),\n 'total_contacts' => count($contactIds),\n 'existing_contacts' => count($existingContactsData),\n 'missing_contacts' => count($missingContactIds),\n ]);\n\n // Sync missing contacts using batch API\n try {\n $syncedContactsData = $this->batchSyncCrmObjects('contacts', $missingContactIds);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to sync missing contacts', [\n 'size' => count($missingContactIds),\n 'error' => $e->getMessage(),\n ]);\n $syncedContactsData = [];\n }\n\n return $existingContactsData + $syncedContactsData;\n }\n\n private function batchSyncCrmObjects(string $objectType, array $crmIds): array\n {\n $syncObjects = [];\n $crmObjectIds = array_values($crmIds);\n\n foreach (array_chunk($crmObjectIds, self::BATCH_SIZE) as $chunk) {\n try {\n $objects = $objectType === 'companies' ?\n $this->client->getCompaniesByIds($chunk, $this->getCompanyFields()) :\n $this->client->getContactsByIds($chunk, $this->getContactFields());\n\n foreach ($objects as $objectId => $objectData) {\n $this->importCrmObject($objectType, (string) $objectId, $objectData, $syncObjects);\n }\n\n $this->logger->info('[' . $this->getDisplayName() . '] Batch synced ' . $objectType, [\n 'requested_count' => count($chunk),\n 'synced_count' => count($objects),\n ]);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Batch ' . $objectType . ' sync failed', [\n 'ids' => $chunk,\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n return $syncObjects;\n }\n\n private function importCrmObject(string $objectType, string $objectId, mixed $objectData, array &$syncObjects): void\n {\n try {\n $object = $objectType === 'companies' ?\n $this->importAccount($objectData) :\n $this->importContact($objectData);\n\n if ($object) {\n $syncObjects[$object->getCrmProviderId()] = $object->getId();\n }\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to import batch ' . $objectType, [\n 'id' => $objectId,\n 'error' => $e->getMessage(),\n ]);\n }\n }\n\n /**\n * Prepare associations for a single opportunity\n *\n * The return value is an array with the following structure:\n * [\n * 'companies' => [\n * $companyCrmId => $companyId,\n * ...\n * ],\n * 'contacts' => [\n * $contactCrmId => $contactId,\n * ...\n * ],\n * 'account_id' => $accountId,\n * ]\n */\n private function prepareAssociationsForOpportunity(\n string $oppCrmId,\n array $companyAssociations,\n array $contactAssociations,\n array $associationsData\n ): array {\n $associations = [\n 'companies' => [],\n 'contacts' => [],\n 'account_id' => null, // Primary account for opportunity\n ];\n\n $oppCompanyIds = $companyAssociations[$oppCrmId] ?? [];\n foreach ($oppCompanyIds as $companyCrmId) {\n if (isset($associationsData['company_id_mappings'][$companyCrmId])) {\n $associations['companies'][$companyCrmId] = $associationsData['company_id_mappings'][$companyCrmId];\n\n // Set primary account (first company becomes primary account)\n if ($associations['account_id'] === null) {\n $associations['account_id'] = $associationsData['company_id_mappings'][$companyCrmId];\n }\n }\n }\n\n $oppContactIds = $contactAssociations[$oppCrmId] ?? [];\n foreach ($oppContactIds as $contactCrmId) {\n if (isset($associationsData['contact_id_mappings'][$contactCrmId])) {\n $associations['contacts'][$contactCrmId] = $associationsData['contact_id_mappings'][$contactCrmId];\n }\n }\n\n return $associations;\n }\n\n /**\n * Update only associations for an opportunity\n */\n private function updateOpportunityAssociations(Opportunity $opportunity, array $associations): void\n {\n // Update contact associations\n $this->importOpportunityContacts($opportunity, $associations['contacts']);\n\n // Update company (account) associations\n $this->updateOpportunityAccount($opportunity, $associations['account_id']);\n }\n\n /**\n * Remove all contact associations from an opportunity\n */\n private function removeAllOpportunityContacts(Opportunity $opportunity): void\n {\n $currentCount = (int) $opportunity->contacts()->count();\n\n if ($currentCount > 0) {\n $opportunity->contacts()->detach();\n\n $this->logger->info('[' . $this->getDisplayName() . '] Removed all contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'removed_count' => $currentCount,\n ]);\n }\n }\n\n private function updateOpportunityAccount(Opportunity $opportunity, ?int $accountId): void\n {\n if ($accountId === null) {\n // No account ID provided - keep current account\n return;\n }\n\n $currentAccountId = $opportunity->getAccountId();\n\n // Only update if account has changed\n if ($currentAccountId !== $accountId) {\n $opportunity->account_id = $accountId;\n $opportunity->save();\n\n $this->logger->info('[' . $this->getDisplayName() . '] Updated opportunity account association', [\n 'opportunity_id' => $opportunity->getId(),\n 'old_account_id' => $currentAccountId,\n 'new_account_id' => $accountId,\n ]);\n }\n }\n\n /**\n * Find existing opportunities by external IDs (OPTIMIZED VERSION)\n * Uses batch query for better performance\n */\n private function findExistingOpportunities(array $crmIds): Collection\n {\n return $this->crmEntityRepository\n ->findOpportunitiesByExternalIds($this->config, $crmIds);\n }\n\n private function processOpportunityBatch(array $opportunities): int\n {\n $syncedOpportunities = $this->importOpportunityBatch($opportunities);\n\n return count($syncedOpportunities['success'] ?? []);\n }\n\n /**\n * Convert single deal associations from HubSpot format to internal format\n * Handles both HubSpot SDK objects and array formats\n *\n * @param array $opportunityAssociations Raw associations from HubSpot API or pre-processed\n *\n * @return array Processed associations with DB IDs\n */\n private function convertDealAssociations(array $opportunityAssociations): array\n {\n $associations = $this->initializeAssociationsStructure();\n\n if (empty($opportunityAssociations)) {\n return $associations;\n }\n\n $associationIds = $this->extractAssociationIds($opportunityAssociations);\n\n $this->processCompanyAssociations($associationIds, $associations);\n $this->processContactAssociations($associationIds, $associations);\n\n return $associations;\n }\n\n private function initializeAssociationsStructure(): array\n {\n return [\n 'companies' => [],\n 'contacts' => [],\n 'account_id' => null, // Primary account for opportunity\n ];\n }\n\n private function extractAssociationIds(array $opportunityAssociations): array\n {\n $associationIds = [];\n\n foreach ($opportunityAssociations as $type => $associationData) {\n if (! empty($associationData)) {\n $associationIds[$type] = $this->convertSingleDealAssociations($associationData);\n }\n }\n\n return $associationIds;\n }\n\n private function processCompanyAssociations(array $associationIds, array &$associations): void\n {\n if (empty($associationIds['companies'])) {\n return;\n }\n\n $companyId = $associationIds['companies'][0];\n $account = $this->findOrSyncAccount($companyId);\n\n if ($account instanceof Account) {\n $associations['companies'][$companyId] = $account->getId();\n $associations['account_id'] = $account->getId();\n }\n }\n\n private function processContactAssociations(array $associationIds, array &$associations): void\n {\n if (empty($associationIds['contacts'])) {\n return;\n }\n\n foreach ($associationIds['contacts'] as $contactId) {\n $contact = $this->findOrSyncContact($contactId);\n\n if ($contact instanceof Contact) {\n $associations['contacts'][$contactId] = $contact->getId();\n }\n }\n }\n\n private function findOrSyncAccount(string $companyId): ?Account\n {\n $account = $this->crmEntityRepository->findAccountByExternalId($this->config, $companyId);\n\n if (! $account instanceof Account) {\n $account = $this->syncAccount($companyId);\n }\n\n return $account;\n }\n\n private function findOrSyncContact(string $contactId): ?Contact\n {\n $contact = $this->crmEntityRepository->findContactByExternalId($this->config, $contactId);\n\n if (! $contact instanceof Contact) {\n $contact = $this->syncContact($contactId);\n }\n\n return $contact;\n }\n\n private function convertSingleDealAssociations($opportunityAssociations = null): array\n {\n $associationData = [];\n\n if ($opportunityAssociations === null) {\n return $associationData;\n }\n\n // Handle array input (from extractAssociationIds)\n if (is_array($opportunityAssociations)) {\n return $opportunityAssociations;\n }\n\n // Handle CollectionResponseAssociatedId object\n if ($opportunityAssociations instanceof CollectionResponseAssociatedId) {\n foreach ($opportunityAssociations->getResults() as $association) {\n $associationData[] = $association->getId();\n }\n }\n\n return $associationData;\n }\n\n private function importOrUpdateOpportunity($crmData, ?bool $exists = null): ?Opportunity\n {\n if (empty($crmData['properties'])) {\n return null;\n }\n\n $crmId = (string) $crmData['id'];\n $properties = $crmData['properties'];\n $associations = $crmData['associations'] ?? [];\n\n $opportunityExists = $exists ?? (bool) $this->crmEntityRepository->findOpportunityByExternalId(\n $this->config,\n $crmId\n );\n\n if ($opportunityExists) {\n return $this->updateOpportunity($crmId, $properties, $associations);\n }\n\n return $this->createOpportunity($crmId, $properties, $associations);\n }\n\n /**\n * Create new opportunity\n */\n private function createOpportunity(string $crmId, array $properties, array $associations): ?Opportunity\n {\n $accountId = $this->resolveAccountId($associations);\n if (! $accountId) {\n return null;\n }\n\n $businessProcess = $this->resolveBusinessProcess($properties['pipeline'] ?? null);\n if (! $businessProcess) {\n return null;\n }\n\n $stage = $this->resolveStage($businessProcess, $properties['dealstage'] ?? null);\n if (! $stage) {\n return null;\n }\n\n $data = $this->buildOpportunityData($properties, $accountId, $businessProcess, $stage);\n\n $attributes = [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $crmId,\n ];\n\n $values = array_merge($attributes, $data);\n\n $opportunity = $this->crmEntityRepository->upsertOpportunity($attributes, $values);\n\n $this->importExternalFieldData($properties, $opportunity->getId());\n $this->importOpportunityContacts($opportunity, $associations['contacts']);\n\n if ($opportunity->wasRecentlyCreated) {\n MatchActivitiesToNewOpportunity::dispatch($opportunity->getId());\n }\n\n return $opportunity;\n }\n\n /**\n * Update existing opportunity\n */\n private function updateOpportunity(string $crmId, array $properties, array $associations): Opportunity\n {\n $accountId = $this->resolveAccountId($associations);\n $businessProcess = $this->resolveBusinessProcess($properties['pipeline'] ?? null);\n $stage = $businessProcess ? $this->resolveStage($businessProcess, $properties['dealstage'] ?? null) : null;\n\n $data = $this->buildOpportunityData($properties, $accountId, $businessProcess, $stage);\n\n $attributes = [\n 'crm_configuration_id' => $this->config->getId(),\n 'crm_provider_id' => $crmId,\n ];\n\n $values = array_merge($attributes, $data);\n $opportunity = $this->crmEntityRepository->upsertOpportunity($attributes, $values);\n\n $this->importExternalFieldData($properties, $opportunity->getId());\n $this->updateOpportunityAssociations($opportunity, $associations);\n\n return $opportunity;\n }\n\n private function resolveAccountId(array $associations): ?int\n {\n if (! empty($associations['account_id'])) {\n return $associations['account_id'];\n }\n\n if (empty($associations)) {\n return null;\n }\n\n // Fallback: use first company as account (currently SDK returns one company)\n foreach ($associations['companies'] as $accountId) {\n return $accountId;\n }\n\n return null;\n }\n\n private function buildOpportunityData(\n array $properties,\n ?int $accountId,\n ?BusinessProcess $businessProcess,\n ?Stage $stage\n ): array {\n $ownerId = null;\n $profile = null;\n if (! empty($properties['hubspot_owner_id'])) {\n $ownerId = $properties['hubspot_owner_id'];\n $profile = $this->getCachedOwnerProfile((string) $ownerId);\n }\n\n $name = 'Unknown';\n if (isset($properties['dealname'])) {\n $name = mb_strimwidth($properties['dealname'], 0, 128);\n }\n\n $amount = $this->resolveAmount($properties);\n $currency = $properties['deal_currency_code'] ?? null;\n\n $closeDate = null;\n if (! empty($properties['closedate'])) {\n $closeDate = Carbon::parse($properties['closedate'])->format('Y-m-d');\n }\n\n $remotelyCreatedAt = null;\n if (! empty($properties['createdate']) && strtotime($properties['createdate'])) {\n $date = $this->parseCleanDatetime($properties['createdate']);\n $remotelyCreatedAt = $date?->format('Y-m-d H:i:s');\n }\n\n $closedStages = $this->getClosedDealStages();\n $isWon = in_array($properties['dealstage'], $closedStages['won']);\n $isLost = in_array($properties['dealstage'], $closedStages['lost']);\n\n $data = [\n 'team_id' => $this->team->getId(),\n 'user_id' => $profile ? $profile->user_id : null,\n 'owner_id' => $ownerId,\n 'name' => $name,\n 'value' => ! empty($amount) ? $amount : null,\n 'currency_code' => CurrencyFormatter::formatCode($currency),\n 'close_date' => $closeDate,\n 'is_closed' => $isWon || $isLost,\n 'is_won' => $isWon,\n 'remotely_created_at' => $remotelyCreatedAt,\n 'probability' => $this->resolveDealProbability($properties['hs_deal_stage_probability']),\n 'forecast_category' => $this->resolveForecastCategory($properties['hs_manual_forecast_category']),\n ];\n\n if ($accountId) {\n $data['account_id'] = $accountId;\n }\n\n if ($stage) {\n $data['stage_id'] = $stage->id;\n }\n\n if ($businessProcess) {\n $recordType = $this->getCachedBusinessProcessRecordType($businessProcess);\n if ($recordType) {\n $data['record_type_id'] = $recordType->id;\n }\n }\n\n return $data;\n }\n\n private function getCachedOwnerProfile(string $ownerId): mixed\n {\n $cacheKey = $this->config->getId() . ':' . $ownerId;\n if (array_key_exists($cacheKey, $this->cachedOwnerProfiles)) {\n return $this->cachedOwnerProfiles[$cacheKey];\n }\n\n $profile = $this->crmEntityRepository->findProfileByExternalId($this->config, $ownerId);\n $this->cachedOwnerProfiles[$cacheKey] = $profile;\n\n return $profile;\n }\n\n private function getCachedBusinessProcessRecordType(BusinessProcess $businessProcess): mixed\n {\n $cacheKey = $this->config->getId() . ':' . $businessProcess->getId();\n if (array_key_exists($cacheKey, $this->cachedRecordTypes)) {\n return $this->cachedRecordTypes[$cacheKey];\n }\n\n $recordType = $this->crmEntityRepository->getBusinessProcessRecordType($businessProcess);\n $this->cachedRecordTypes[$cacheKey] = $recordType;\n\n return $recordType;\n }\n\n private function resolveBusinessProcess(?string $pipelineId): ?BusinessProcess\n {\n if ($pipelineId === null) {\n return null;\n }\n\n $cacheKey = $this->getBusinessProcessCacheKey($pipelineId);\n if (isset($this->cachedBusinessProcesses[$cacheKey])) {\n return $this->cachedBusinessProcesses[$cacheKey];\n }\n\n $businessProcess = $this->getBusinessProcess($pipelineId);\n\n if (! $businessProcess instanceof BusinessProcess) {\n $this->importStages();\n $businessProcess = $this->getBusinessProcess($pipelineId);\n }\n\n if (! $businessProcess instanceof BusinessProcess) {\n $this->logger->info(\n '[HubSpot] Deal is not attached to a pipeline',\n [\n 'pipeline' => $pipelineId]\n );\n }\n\n $this->cachedBusinessProcesses[$cacheKey] = $businessProcess;\n\n return $businessProcess;\n }\n\n private function getBusinessProcess(string $pipelineId): ?BusinessProcess\n {\n return $this->crmEntityRepository->findBusinessProcessesByExternalId($this->config, $pipelineId);\n }\n\n private function getBusinessProcessCacheKey(string $pipelineId): string\n {\n return $this->config->getId() . '_' . $pipelineId;\n }\n\n private function resolveStage(BusinessProcess $businessProcess, ?string $stageId): ?Stage\n {\n if (empty($stageId)) {\n return null;\n }\n\n $cacheKey = $this->config->getId() . ':' . $businessProcess->getId() . ':' . $stageId;\n if (isset($this->cachedStages[$cacheKey])) {\n return $this->cachedStages[$cacheKey];\n }\n\n $stage = $this->crmEntityRepository->getPipelineStageByConditions(\n $businessProcess,\n [\n 'crm_provider_id' => $stageId,\n 'type' => Stage::TYPE_OPPORTUNITY,\n ]\n );\n\n if ($stage === null) {\n $this->importStages(null, $stageId);\n }\n\n if ($stage === null) {\n $this->logger->info('[HubSpot] Stage does not exist => ' . $stageId);\n }\n\n $this->cachedStages[$cacheKey] = $stage;\n\n return $stage;\n }\n\n private function resolveAmount(array $properties): ?string\n {\n $amount = null;\n if (! empty($properties['amount'])) {\n $amount = str_replace(',', '', $properties['amount']);\n }\n\n if ($this->config->hasDefaultCurrencyFieldSet()) {\n $valueFieldName = $this->config->getDefaultCurrencyField()->getCrmProviderId();\n $amount = $properties[$valueFieldName] ?? $amount;\n }\n\n return $amount;\n }\n\n private function parseCleanDatetime(string $datetime): ?Carbon\n {\n // Treat pre-1980 values as invalid\n $minValidDate = Carbon::parse('1980-01-01 00:00:00');\n\n try {\n $date = Carbon::parse($datetime);\n\n if ($minValidDate->gt($date)) {\n return null;\n }\n\n return $date;\n } catch (Exception) {\n return null; // On parse error, treat as null\n }\n }\n\n private function resolveDealProbability(?string $stageProbability): int\n {\n if ($stageProbability === null) {\n return 0;\n }\n\n $probability = (float) $stageProbability;\n\n return $probability > 1 ? 0 : (int) ($probability * 100);\n }\n\n private function resolveForecastCategory(?string $forecastCategory): string\n {\n if (! $forecastCategory) {\n return Forecast::FORECAST_CATEGORY_UNCATEGORIZED;\n }\n\n $forecastCategory = str_replace('_', ' ', $forecastCategory);\n\n return ucwords(strtolower($forecastCategory));\n }\n\n private function importExternalFieldData(array $properties, int $opportunityId): void\n {\n $this->importOpportunityCrmFieldData(\n $properties,\n $this->getCachedOpportunitySyncableFields(),\n $opportunityId\n );\n }\n\n private function getCachedOpportunitySyncableFields(): array\n {\n $cacheKey = (string) $this->config->getId();\n if (! isset($this->cachedOpportunitySyncableFields[$cacheKey])) {\n $this->cachedOpportunitySyncableFields[$cacheKey] = $this->getOpportunitySyncableFields();\n }\n\n return $this->cachedOpportunitySyncableFields[$cacheKey];\n }\n\n private function importOpportunityContacts(Opportunity $opportunity, array $associations): void\n {\n // Handle empty or missing contact associations\n if (empty($associations)) {\n // Remove all existing contact associations if none provided\n $this->removeAllOpportunityContacts($opportunity);\n\n return;\n }\n\n // Use differential sync approach for better performance and accuracy\n $this->syncOpportunityContactsDifferential($opportunity, $associations);\n }\n\n /**\n * Sync opportunity contacts using differential approach\n * This compares current vs new associations and only makes necessary changes\n */\n private function syncOpportunityContactsDifferential(Opportunity $opportunity, array $contactAssociations): void\n {\n $currentContactCrmIds = $this->getCurrentContactCrmIds($opportunity);\n $contactAssociationIds = array_keys($contactAssociations);\n\n $contactsToAdd = array_diff($contactAssociationIds, $currentContactCrmIds);\n $contactsToRemove = array_diff($currentContactCrmIds, $contactAssociationIds);\n\n if (empty($contactsToAdd) && empty($contactsToRemove)) {\n return;\n }\n\n $this->logContactAssociationChanges($opportunity, $currentContactCrmIds, $contactAssociations, $contactsToAdd, $contactsToRemove);\n\n $this->removeContactAssociations($opportunity, $contactsToRemove);\n $this->addContactAssociations($opportunity, $contactsToAdd, $contactAssociations);\n }\n\n private function getCurrentContactCrmIds(Opportunity $opportunity): array\n {\n return $opportunity->contacts()\n ->pluck('contacts.crm_provider_id')\n ->toArray();\n }\n\n private function logContactAssociationChanges(\n Opportunity $opportunity,\n array $currentContactCrmIds,\n array $contactAssociations,\n array $contactsToAdd,\n array $contactsToRemove\n ): void {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact association changes', [\n 'opportunity_id' => $opportunity->getId(),\n 'current_contacts' => $currentContactCrmIds,\n 'new_contacts' => $contactAssociations,\n 'contacts_to_add' => $contactsToAdd,\n 'contacts_to_remove' => $contactsToRemove,\n ]);\n }\n\n private function removeContactAssociations(Opportunity $opportunity, array $contactsToRemove): void\n {\n if (empty($contactsToRemove)) {\n return;\n }\n\n $contactsToDetach = $opportunity->contacts()\n ->whereIn('contacts.crm_provider_id', $contactsToRemove)\n ->pluck('contacts.id')\n ->toArray();\n\n if (! empty($contactsToDetach)) {\n $opportunity->contacts()->detach($contactsToDetach);\n\n $this->logger->info('[' . $this->getDisplayName() . '] Removed contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'removed_contact_crm_ids' => $contactsToRemove,\n 'removed_contact_count' => count($contactsToDetach),\n ]);\n }\n }\n\n private function addContactAssociations(Opportunity $opportunity, array $contactsToAdd, array $contactAssociations): void\n {\n if (empty($contactsToAdd)) {\n return;\n }\n\n $contactsAdded = [];\n foreach ($contactsToAdd as $crmId) {\n $id = $contactAssociations[$crmId];\n\n if ($this->attachSingleContact($opportunity, (string) $crmId, $id)) {\n $contactsAdded[] = $crmId;\n }\n }\n\n $this->logAddedContacts($opportunity, $contactsAdded);\n }\n\n private function attachSingleContact(Opportunity $opportunity, string $crmId, int $id): bool\n {\n try {\n return $this->performContactAttachment($opportunity, $id, $crmId);\n } catch (\\Throwable $e) {\n $this->logger->warning('[' . $this->getDisplayName() . '] Failed to add contact association', [\n 'opportunity_id' => $opportunity->getId(),\n 'contact_crm_id' => $crmId,\n 'error' => $e->getMessage(),\n ]);\n\n return false;\n }\n }\n\n private function performContactAttachment(Opportunity $opportunity, int $contactId, string $crmId): bool\n {\n try {\n $opportunity->contacts()->attach($contactId, [\n 'crm_provider_id' => $crmId,\n ]);\n\n return true;\n } catch (\\Illuminate\\Database\\QueryException $e) {\n if (str_contains($e->getMessage(), 'Duplicate entry')) {\n $this->logger->info('[' . $this->getDisplayName() . '] Contact association already exists', [\n 'contact_id' => $contactId,\n 'contact_crm_id' => $crmId,\n 'opportunity_id' => $opportunity->getId(),\n ]);\n\n return false;\n }\n\n throw $e;\n }\n }\n\n private function logAddedContacts(Opportunity $opportunity, array $contactsAdded): void\n {\n if (! empty($contactsAdded)) {\n $this->logger->info('[' . $this->getDisplayName() . '] Added contact associations', [\n 'opportunity_id' => $opportunity->getId(),\n 'added_contact_crm_ids' => $contactsAdded,\n 'added_contacts_count' => count($contactsAdded),\n ]);\n }\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}]...
|
1996073461129327348
|
8566805675520198815
|
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
Search History
Hubspot
New Line
Replace History
Replace
New Line
Previous Occurrence
Next Occurrence
Search All
Search Backward
Search Forward
Match сase
Words
Regex
?
Close
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28:10] local.INFO: [ScheduleBotCommand] Number of activities to be captured: 0 {"correlation_id":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"d4ce87a9-6ca5-4efe-99b3-4220893270d0","trace_id":"724e8238-2ed5-4089-9509-9c7c12a3c373"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28: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":"172d1ae8-b8cc-4804-bed9-e32d074e265c","trace_id":"4817cdef-8d3e-4914-8bee-feffb18efe1b"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1499,"provider":"hubspot"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:17] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1499,"provider":"hubspot","refreshToken":"96f94c623a404e02ebdbf07f1b75707bb6cdbf848cbf45d418baf608c41a8d86","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring start {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.NOTICE: Monitoring end {"correlation_id":"31aa6b7d-00d6-448a-bdcc-a3d215b4aeb5","trace_id":"b8eb7fe5-8471-4ffb-9bfa-a804c8e1ff72"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountObserver] Access token was modified, encrypting {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [SocialAccountService] Token refreshed {"socialAccountId":1499,"provider":"hubspot","state":"connected"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:18] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"hubspot","crm_owner":148,"team_id":2} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.INFO: [Hubspot] Failed to fetch opportunity {"crm_id":"374720564","reason":"[429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
"} {"correlation_id":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28:19] local.ERROR: [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{"status":"error","message":"You have reached your ten_secondly_rolling limit.","errorType":"RATE_LIMIT","correlationId" (truncated...)
{"exception":"[object] (HubSpot\\Client\\Crm\\Deals\\ApiException(code: 429): [429] Client error: `GET https://api.hubapi.com/crm/v3/objects/deals/374720564?properties=hs_object_id%2Cdealname&associations=companies%2Ccontacts&archived=0` resulted in a `429 Too Many Requests` response:
{\"status\":\"error\",\"message\":\"You have reached your ten_secondly_rolling limit.\",\"errorType\":\"RATE_LIMIT\",\"correlationId\" (truncated...)
at /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php:704)
[stacktrace]
#0 /home/jiminny/vendor/hubspot/api-client/codegen/Crm/Deals/Api/BasicApi.php(676): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getByIdWithHttpInfo('374720564', 'hs_object_id,de...', 'companies,conta...', false, NULL)
#1 /home/jiminny/app/Services/Crm/Hubspot/Client.php(212): HubSpot\\Client\\Crm\\Deals\\Api\\BasicApi->getById('374720564', 'hs_object_id,de...', 'companies,conta...')
#2 /home/jiminny/app/Services/Crm/Hubspot/ServiceTraits/OpportunitySyncTrait.php(130): Jiminny\\Services\\Crm\\Hubspot\\Client->getOpportunityById('374720564', Array)
#3 /home/jiminny/app/Console/Commands/JiminnyDebugCommand.php(351): Jiminny\\Services\\Crm\\Hubspot\\Service->syncOpportunity('374720564')
#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":"273355f2-6315-4b20-bc9a-c26c681d6344","trace_id":"5ea79a26-c838-48e8-9913-93ad508146a6"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28: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":"dcb9b24b-e2e5-41fe-81db-212b3ca9ff7d","trace_id":"1ea62b83-9639-41e3-a523-26404c39fa80"}
[2026-05-07 12:28:24] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"mailbox:batch:process","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] STARTING batch process {"host":"docker_lamp_1"} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] local.INFO: [EmailSchedule] FINISHED batch process {"host":"docker_lamp_1","processed":0} {"correlation_id":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:24] 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":"d191d5c6-133f-43e1-8ed4-d285d0c768b8","trace_id":"67798138-bdb7-4bd7-8b32-377663219a88"}
[2026-05-07 12:28:27] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"conference:monitor:count","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: Running conference:monitor:count command for activities in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] local.INFO: [conference:monitor:count] No activities found in (2026-05-07 12:26:00, 2026-05-07 12:28:00] {"correlation_id":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:27] 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":"a4e5e18f-9f8c-4196-ace0-bf664d4827d9","trace_id":"d75cb10b-4c76-4c00-84d4-26efeb738e17"}
[2026-05-07 12:28:30] local.INFO: Jiminny\Console\Commands\Command::run Memory usage before starting command {"command":"calendar:sync","memoryBeforeCommandInMb":62.0,"memoryPeakBeforeCommandInMb":99.727} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:30] local.NOTICE: Calendar sync start {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:30] 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":"3789f06a-4f0c-4b12-be80-d6a36e089d1b","trace_id":"6ce89147-1624-456d-9e75-f4948f2c5db8"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1393,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1393,"provider":"google","refreshToken":"5aa7e2d96b53201cd16fca5d2e4ef3ad03320971fc064781d18aee3ae7b99fbf","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1393,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1387,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1387,"provider":"google","refreshToken":"8157ac6de94842937194009e9c50e459253600f799dacf6a40755ffdbeb5bba6","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1387,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1348,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1348,"provider":"google","refreshToken":"9e7d13d3032d0cb1b79d8e95aef01383e8e91eb52ff8ee960c8a0b6b95cd8c73","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1348,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1361,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:31] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1361,"provider":"google","refreshToken":"6c843da199c2b9907445329304fcc4ec5057a4ee748d8299641764395c08e1fd","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1361,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1310,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1310,"provider":"google","refreshToken":"e34818922c2830a660813a63f6169a4a9a992ae2cccd7dc8dd7796cfdb470ef1","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1310,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1333,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1333,"provider":"google","refreshToken":"6c902986546d8e8da1dc539b046cdc1d458f519acc972e5b5f1d6a1a295165e0","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1333,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1368,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1368,"provider":"google","refreshToken":"d2f128898ff8543bd16b69cfae37896ab85119b0f5ed2b431d739593bb600333","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1368,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1365,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:32] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1365,"provider":"google","refreshToken":"7676e4a9afcd082b413248ab5ec6e487021fec6a9bdf315860a59cefad9caad8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1365,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1364,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1364,"provider":"google","refreshToken":"dd5882ebce76e645292ce33ae74238abbb77c0a4ecc6a2bfe723cad82e72ba8e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1364,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1370,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1370,"provider":"office","refreshToken":"b7ee8035306d0043cea6e00e7c4fe14f745e44074a1194db62a31cdf8b70af3e","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] 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: e890fdc1-dbe8-4a59-ae57-2af6bced3c00 Correlation ID: 57554cdf-16df-47f1-b0d9-5f0b8da37afe Timestamp: 2026-05-07 12:28:33Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:33Z\",\"trace_id\":\"e890fdc1-dbe8-4a59-ae57-2af6bced3c00\",\"correlation_id\":\"57554cdf-16df-47f1-b0d9-5f0b8da37afe\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1370,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1202,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:33] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1202,"provider":"office","refreshToken":"b458799ccc29b21a6e2eb5260fdb63e49ccba21bf942a3973fb63799bd7f0afe","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] 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: 2a3e5b60-5770-46f2-aca6-7b0527363000 Correlation ID: 57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2 Timestamp: 2026-05-07 12:28:34Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:34Z\",\"trace_id\":\"2a3e5b60-5770-46f2-aca6-7b0527363000\",\"correlation_id\":\"57bb0b73-9ea6-4bcf-a8f4-6e211dbb94e2\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1202,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: Calendar sync job dispatched {"calendar_id":501} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1300,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1300,"provider":"google","refreshToken":"4b811db0725fd9602a95943519a7da935e2a5065da7d9ebfcb170752e3e1ddb8","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Account has been deleted"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:34] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1300,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1409,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1409,"provider":"google","refreshToken":"e2a3f2d06894894eed1ee87d9db1ace77d4d42ee6e1288a8940ad2c10333b0c4","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","responseBody":{"error":"invalid_grant","error_description":"Bad Request"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1409,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1352,"provider":"google"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1352,"provider":"google","refreshToken":"dd4b16b00fdc1216da6b717c02338c073636e29162826b2de6db3f064fc029eb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","responseBody":{"error":"unauthorized_client","error_description":"Unauthorized"}} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1352,"provider":"google","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1296,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1296,"provider":"office","refreshToken":"011ae723c9d800c674e0b4be76f49fc046dac7d501b66c59ef0d9549cfa56ae5","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [CrmOwnerResolver] Integration owner matched as CRM Owner {"crm_provider":"integration-app","crm_owner":1695,"team_id":3143} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token retrieved {"socialAccountId":1502,"provider":"google"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] 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: 2e34e335-a76d-40e5-bc50-3861392e4c00 Correlation ID: 9db5b389-6165-4feb-8e6e-bedc369e1c87 Timestamp: 2026-05-07 12:28:35Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:35Z\",\"trace_id\":\"2e34e335-a76d-40e5-bc50-3861392e4c00\",\"correlation_id\":\"9db5b389-6165-4feb-8e6e-bedc369e1c87\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1296,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":391,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:35] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":391,"provider":"office","refreshToken":"00045eebae0f39b34887c6d53f92ae78064f7145e1f4b67754aebd03cfb2d881","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [Google Calendar] Failed to watch channel for calendar {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.WARNING: [Calendar] Sync failed {"calendarId":"a33076c1-8d97-431a-99f0-85c9524e118b","code":400,"reason":"{
\"error\": {
\"errors\": [
{
\"domain\": \"global\",
\"reason\": \"push.webhookUrlNotHttps\",
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
],
\"code\": 400,
\"message\": \"WebHook callback must be HTTPS: /webhook/calendar/google?resourceType=event\"
}
}"} {"correlation_id":"3015918c-9edf-487d-b1d0-97c9d00ea6b1","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] 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: 6eba7173-b781-4e55-b1fb-1087ed023000 Correlation ID: 3086e346-c6eb-4f1c-8b1d-a477ce3821f4 Timestamp: 2026-05-07 12:28:36Z\",\"error_codes\":[7000215],\"timestamp\":\"2026-05-07 12:28:36Z\",\"trace_id\":\"6eba7173-b781-4e55-b1fb-1087ed023000\",\"correlation_id\":\"3086e346-c6eb-4f1c-8b1d-a477ce3821f4\",\"error_uri\":\"https://login.microsoftonline.com/error?code=7000215\"}"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.INFO: [SocialAccountObserver] Saving model {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:36] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":391,"provider":"office","reason":"Flow refresh required."} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Fetching token {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Token needs refreshing {"socialAccountId":1271,"provider":"office"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [EncryptedTokenManager] Generating access token. {"mode":"legacy"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.INFO: [SocialAccountService] Refreshing token from provider {"socialAccountId":1271,"provider":"office","refreshToken":"118cde2c06993147b07ccaec4cbcd5026a819dea6c71081166a492933e392afb","state":"full-refresh"} {"correlation_id":"d543a089-fd32-4522-9ffe-1494e562b741","trace_id":"564a362b-7ddb-49f0-a33a-b807b0440231"}
[2026-05-07 12:28:37] local.ERROR: [SocialAccountService] Failed to refresh token {"socialAccountId":1271,"provider":"office","responseBody":"{\"error\":\"invalid_client\",\"error_description\":\"AADSTS7000215: Invalid client secret provided...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
3636
|
134
|
11
|
2026-05-07T12:32:11.370146+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-07/1778 /Users/lukas/.screenpipe/data/data/2026-05-07/1778157131370_m2.jpg...
|
PhpStorm
|
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Search
syncOpportunity (SyncCrmEntitiesTrait .../a Search
syncOpportunity (SyncCrmEntitiesTrait .../app/Services/Crm/IntegrationApp/ServiceTraits), public method
syncOpportunity (SyncCrmEntitiesInterface .../app/Contracts/Services/Crm), public abstract method
syncOpportunity (Service .../app/Services/Crm/Pipedrive), public method
syncOpportunity (Service .../app/Services/Crm/Copper), public method
syncOpportunity (OpportunitySyncTrait .../app/Services/Crm/Hubspot/ServiceTraits), public method
syncOpportunity (Service .../app/Services/Crm/Dummy), public method
syncOpportunity (ServiceInterface .../app/Contracts/Services/Crm), public abstract method
syncOpportunity (BullhornService .../app/Services/Crm/Bullhorn), public method
syncOpportunity (Service .../app/Services/Crm/Close), public method
syncOpportunity (Service .../app/Services/Crm/Salesforce), public method
Choose Declaration...
|
[{"role":"AXTextField","text [{"role":"AXTextField","text":"Search","depth":1,"on_screen":false,"role_description":"text field","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"syncOpportunity (SyncCrmEntitiesTrait .../app/Services/Crm/IntegrationApp/ServiceTraits), public method","depth":4,"bounds":{"left":0.21043883,"top":0.79010373,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"syncOpportunity (SyncCrmEntitiesInterface .../app/Contracts/Services/Crm), public abstract method","depth":4,"bounds":{"left":0.21043883,"top":0.8076616,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"syncOpportunity (Service .../app/Services/Crm/Pipedrive), public method","depth":4,"bounds":{"left":0.21043883,"top":0.82521945,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"syncOpportunity (Service .../app/Services/Crm/Copper), public method","depth":4,"bounds":{"left":0.21043883,"top":0.8427773,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"syncOpportunity (OpportunitySyncTrait .../app/Services/Crm/Hubspot/ServiceTraits), public method","depth":4,"bounds":{"left":0.21043883,"top":0.8603352,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"syncOpportunity (Service .../app/Services/Crm/Dummy), public method","depth":4,"bounds":{"left":0.21043883,"top":0.87789303,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"syncOpportunity (ServiceInterface .../app/Contracts/Services/Crm), public abstract method","depth":4,"bounds":{"left":0.21043883,"top":0.8954509,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"syncOpportunity (BullhornService .../app/Services/Crm/Bullhorn), public method","depth":4,"bounds":{"left":0.21043883,"top":0.91300875,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"syncOpportunity (Service .../app/Services/Crm/Close), public method","depth":4,"bounds":{"left":0.21043883,"top":0.93056667,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"syncOpportunity (Service .../app/Services/Crm/Salesforce), public method","depth":4,"bounds":{"left":0.21043883,"top":0.9481245,"width":0.24567819,"height":0.017557861},"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"Choose Declaration","depth":1,"bounds":{"left":0.2137633,"top":0.76376694,"width":0.23902926,"height":0.026336791},"on_screen":true,"role_description":"text"}]...
|
-5271816033549094748
|
-628994143039882966
|
visual_change
|
accessibility
|
NULL
|
Search
syncOpportunity (SyncCrmEntitiesTrait .../a Search
syncOpportunity (SyncCrmEntitiesTrait .../app/Services/Crm/IntegrationApp/ServiceTraits), public method
syncOpportunity (SyncCrmEntitiesInterface .../app/Contracts/Services/Crm), public abstract method
syncOpportunity (Service .../app/Services/Crm/Pipedrive), public method
syncOpportunity (Service .../app/Services/Crm/Copper), public method
syncOpportunity (OpportunitySyncTrait .../app/Services/Crm/Hubspot/ServiceTraits), public method
syncOpportunity (Service .../app/Services/Crm/Dummy), public method
syncOpportunity (ServiceInterface .../app/Contracts/Services/Crm), public abstract method
syncOpportunity (BullhornService .../app/Services/Crm/Bullhorn), public method
syncOpportunity (Service .../app/Services/Crm/Close), public method
syncOpportunity (Service .../app/Services/Crm/Salesforce), public method
Choose Declaration...
|
3634
|
NULL
|
NULL
|
NULL
|