|
49716
|
NULL
|
0
|
2026-05-18T06:54:01.042087+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087241042_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, 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
6
1
6
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReport
*
* @property int $id
* @property string $uuid
* @property int $team_id
* @property string $type
* @property bool $status
* @property string $frequency
* @property Carbon|null $from
* @property Carbon|null $to
* @property int|null $deal_value_min
* @property int|null $deal_value_max
* @property array $call_types
* @property array $media_types
* @property int|null $call_duration_min
* @property int|null $call_duration_max
* @property array|null $groups
* @property array|null $playbook_categories
* @property array|null $deal_at_call_stages
* @property array|null $current_deal_stages
* @property array $recipients
* @property string|null $additional_prompt_input
* @property string|null $custom_name
* @property int|null $activity_search_id
* @property int|null $ask_anything_prompt_id
* @property Carbon|null $expires_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property Carbon|null $deleted_at
* @property-read \Jiminny\Models\Team $team
* @property-read \Jiminny\Models\Activity\Search|null $savedSearch
* @property-read \Jiminny\Models\AskAnything\AskAnythingPrompt|null $askAnythingPrompt
*/
class AutomatedReport extends Model
{
use RequiresUUID;
use SoftDeletes;
protected $table = 'automated_reports';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'team_id',
'type',
'status',
'frequency',
'from',
'to',
'deal_value_min',
'deal_value_max',
'call_types',
'media_types',
'call_duration_min',
'call_duration_max',
'groups',
'playbook_categories',
'deal_at_call_stages',
'current_deal_stages',
'recipients',
'jiminny_recipients',
'additional_prompt_input',
'custom_name',
'created_by',
'activity_search_id',
'ask_anything_prompt_id',
'expires_at',
];
protected $hidden = ['uuid'];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'status' => 'boolean',
'from' => 'datetime',
'to' => 'datetime',
'call_types' => 'array',
'media_types' => 'array',
'groups' => 'array',
'playbook_categories' => 'array',
'deal_at_call_stages' => 'array',
'current_deal_stages' => 'array',
'recipients' => 'array',
'jiminny_recipients' => 'array',
'expires_at' => 'date',
'deleted_at' => 'datetime',
];
}
/**
* Get the team that owns the automated report.
*/
public function team()
{
return $this->belongsTo(Team::class);
}
/**
*
* Get the user who created the report.
*/
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
public function savedSearch(): BelongsTo
{
return $this->belongsTo(Search::class, 'activity_search_id');
}
public function askAnythingPrompt(): BelongsTo
{
return $this->belongsTo(AskAnythingPrompt::class, 'ask_anything_prompt_id');
}
public function isAskJiminnyReport(): bool
{
return $this->getType() === AutomatedReportsService::TYPE_ASK_JIMINNY;
}
public function isExpired(): bool
{
$expiresAt = $this->getExpiresAt();
return $expiresAt !== null && $expiresAt->isPast();
}
public function canExecute(): bool
{
if ($this->isAskJiminnyReport()) {
return $this->getActivitySearchId() !== null
&& $this->getAskAnythingPromptId() !== null;
}
return true;
}
public function getActivitySearchId(): ?int
{
return $this->getAttribute('activity_search_id');
}
public function getAskAnythingPromptId(): ?int
{
return $this->getAttribute('ask_anything_prompt_id');
}
public function getExpiresAt(): ?Carbon
{
return $this->getAttribute('expires_at');
}
public function getSavedSearch(): ?Search
{
return $this->getAttribute('savedSearch');
}
public function getAskAnythingPrompt(): ?AskAnythingPrompt
{
return $this->getAttribute('askAnythingPrompt');
}
/**
* Get the ID of the automated report.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the team ID of the automated report.
*
* @return int
*/
public function getTeamId(): int
{
return $this->getAttribute('team_id');
}
/**
* Get the type of the automated report.
*
* @return string
*/
public function getType(): string
{
return $this->getAttribute('type');
}
/**
* Get the status of the automated report.
* True means active, false means inactive.
*
* @return bool
*/
public function getStatus(): bool
{
return $this->getAttribute('status');
}
/**
* Get the frequency of the automated report.
*
* @return string
*/
public function getFrequency(): string
{
return $this->getAttribute('frequency');
}
/**
* Get the from date of the automated report.
*
* @return Carbon|null
*/
public function getFrom(): ?Carbon
{
return $this->getAttribute('from');
}
/**
* Get the to date of the automated report.
*
* @return Carbon|null
*/
public function getTo(): ?Carbon
{
return $this->getAttribute('to');
}
/**
* Get the minimum deal value of the automated report.
*
* @return int|null
*/
public function getDealValueMin(): ?int
{
return $this->getAttribute('deal_value_min');
}
/**
* Get the maximum deal value of the automated report.
*
* @return int|null
*/
public function getDealValueMax(): ?int
{
return $this->getAttribute('deal_value_max');
}
/**
* Get the call types of the automated report.
*
* @return array
*/
public function getCallTypes(): array
{
return $this->getAttribute('call_types') ?? [];
}
public function getMediaTypes(): array
{
return $this->getAttribute('media_types') ?? [];
}
/**
* Get the minimum call duration of the automated report.
*
* @return int|null
*/
public function getCallDurationMin(): ?int
{
return $this->getAttribute('call_duration_min');
}
/**
* Get the maximum call duration of the automated report.
*
* @return int|null
*/
public function getCallDurationMax(): ?int
{
return $this->getAttribute('call_duration_max');
}
/**
* Get the groups of the automated report.
*
* @return array
*/
public function getGroups(): array
{
return $this->getAttribute('groups') ?? [];
}
/**
* Get the playbook categories of the automated report.
*
* @return array
*/
public function getPlaybookCategories(): array
{
return $this->getAttribute('playbook_categories') ?? [];
}
/**
* Get the deal at call stages of the automated report.
*
* @return array
*/
public function getDealAtCallStages(): array
{
return $this->getAttribute('deal_at_call_stages') ?? [];
}
/**
* Get the current deal stages of the automated report.
*
* @return array
*/
public function getCurrentDealStages(): array
{
return $this->getAttribute('current_deal_stages') ?? [];
}
/**
* Get the recipients of the automated report.
*
* @return array
*/
public function getRecipients(): array
{
return $this->getAttribute('recipients') ?? [];
}
/**
* Get the Jiminny's recipients of the automated report.
*
* @return array
*/
public function getJiminnyRecipients(): array
{
return $this->getAttribute('jiminny_recipients') ?? [];
}
/**
* Get the additional prompt input of the automated report.
*
* @return string|null
*/
public function getAdditionalPromptInput(): ?string
{
return $this->getAttribute('additional_prompt_input');
}
public function getCustomName(): ?string
{
return $this->getAttribute('custom_name');
}
/**
* Get the created at date of the automated report.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Get the deleted at date of the automated report.
*
* @return Carbon|null
*/
public function getDeletedAt(): ?Carbon
{
return $this->getAttribute('deleted_at');
}
public function getTeam(): Team
{
return $this->getAttribute('team');
}
public function getCreator(): ?User
{
return $this->getAttribute('creator');
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v1\Api\ActivitiesApi;
use Pipedrive\versions\v1\Api\ActivityFieldsApi;
use Pipedrive\versions\v1\Api\DealFieldsApi;
use Pipedrive\versions\v1\Api\DealsApi;
use Pipedrive\versions\v1\Api\PersonFieldsApi;
use Pipedrive\versions\v1\Api\PersonsApi;
use Pipedrive\versions\v1\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// Official SDK uses getDealsSummary instead of getDeals
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// Official SDK has different method names - test instantiation works
// The actual method names differ from community SDK
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "PersonsApi client instantiated successfully in {$elapsed}ms - method mapping required", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// Official SDK has different method names - test instantiation works
// The actual method names differ from community SDK
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "ActivitiesApi client instantiated successfully in {$elapsed}ms - method mapping required", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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":"6","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"on_screen":true,"role_description":"text"},{"role":"AXStaticText","text":"6","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\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReport\n *\n * @property int $id\n * @property string $uuid\n * @property int $team_id\n * @property string $type\n * @property bool $status\n * @property string $frequency\n * @property Carbon|null $from\n * @property Carbon|null $to\n * @property int|null $deal_value_min\n * @property int|null $deal_value_max\n * @property array $call_types\n * @property array $media_types\n * @property int|null $call_duration_min\n * @property int|null $call_duration_max\n * @property array|null $groups\n * @property array|null $playbook_categories\n * @property array|null $deal_at_call_stages\n * @property array|null $current_deal_stages\n * @property array $recipients\n * @property string|null $additional_prompt_input\n * @property string|null $custom_name\n * @property int|null $activity_search_id\n * @property int|null $ask_anything_prompt_id\n * @property Carbon|null $expires_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property Carbon|null $deleted_at\n * @property-read \\Jiminny\\Models\\Team $team\n * @property-read \\Jiminny\\Models\\Activity\\Search|null $savedSearch\n * @property-read \\Jiminny\\Models\\AskAnything\\AskAnythingPrompt|null $askAnythingPrompt\n */\nclass AutomatedReport extends Model\n{\n use RequiresUUID;\n use SoftDeletes;\n\n protected $table = 'automated_reports';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'team_id',\n 'type',\n 'status',\n 'frequency',\n 'from',\n 'to',\n 'deal_value_min',\n 'deal_value_max',\n 'call_types',\n 'media_types',\n 'call_duration_min',\n 'call_duration_max',\n 'groups',\n 'playbook_categories',\n 'deal_at_call_stages',\n 'current_deal_stages',\n 'recipients',\n 'jiminny_recipients',\n 'additional_prompt_input',\n 'custom_name',\n 'created_by',\n 'activity_search_id',\n 'ask_anything_prompt_id',\n 'expires_at',\n ];\n\n protected $hidden = ['uuid'];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'status' => 'boolean',\n 'from' => 'datetime',\n 'to' => 'datetime',\n 'call_types' => 'array',\n 'media_types' => 'array',\n 'groups' => 'array',\n 'playbook_categories' => 'array',\n 'deal_at_call_stages' => 'array',\n 'current_deal_stages' => 'array',\n 'recipients' => 'array',\n 'jiminny_recipients' => 'array',\n 'expires_at' => 'date',\n 'deleted_at' => 'datetime',\n ];\n }\n\n /**\n * Get the team that owns the automated report.\n */\n public function team()\n {\n return $this->belongsTo(Team::class);\n }\n\n /**\n *\n * Get the user who created the report.\n */\n public function creator(): BelongsTo\n {\n return $this->belongsTo(User::class, 'created_by');\n }\n\n public function savedSearch(): BelongsTo\n {\n return $this->belongsTo(Search::class, 'activity_search_id');\n }\n\n public function askAnythingPrompt(): BelongsTo\n {\n return $this->belongsTo(AskAnythingPrompt::class, 'ask_anything_prompt_id');\n }\n\n public function isAskJiminnyReport(): bool\n {\n return $this->getType() === AutomatedReportsService::TYPE_ASK_JIMINNY;\n }\n\n public function isExpired(): bool\n {\n $expiresAt = $this->getExpiresAt();\n\n return $expiresAt !== null && $expiresAt->isPast();\n }\n\n public function canExecute(): bool\n {\n if ($this->isAskJiminnyReport()) {\n return $this->getActivitySearchId() !== null\n && $this->getAskAnythingPromptId() !== null;\n }\n\n return true;\n }\n\n public function getActivitySearchId(): ?int\n {\n return $this->getAttribute('activity_search_id');\n }\n\n public function getAskAnythingPromptId(): ?int\n {\n return $this->getAttribute('ask_anything_prompt_id');\n }\n\n public function getExpiresAt(): ?Carbon\n {\n return $this->getAttribute('expires_at');\n }\n\n public function getSavedSearch(): ?Search\n {\n return $this->getAttribute('savedSearch');\n }\n\n public function getAskAnythingPrompt(): ?AskAnythingPrompt\n {\n return $this->getAttribute('askAnythingPrompt');\n }\n\n /**\n * Get the ID of the automated report.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the team ID of the automated report.\n *\n * @return int\n */\n public function getTeamId(): int\n {\n return $this->getAttribute('team_id');\n }\n\n /**\n * Get the type of the automated report.\n *\n * @return string\n */\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n /**\n * Get the status of the automated report.\n * True means active, false means inactive.\n *\n * @return bool\n */\n public function getStatus(): bool\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the frequency of the automated report.\n *\n * @return string\n */\n public function getFrequency(): string\n {\n return $this->getAttribute('frequency');\n }\n\n /**\n * Get the from date of the automated report.\n *\n * @return Carbon|null\n */\n public function getFrom(): ?Carbon\n {\n return $this->getAttribute('from');\n }\n\n /**\n * Get the to date of the automated report.\n *\n * @return Carbon|null\n */\n public function getTo(): ?Carbon\n {\n return $this->getAttribute('to');\n }\n\n /**\n * Get the minimum deal value of the automated report.\n *\n * @return int|null\n */\n public function getDealValueMin(): ?int\n {\n return $this->getAttribute('deal_value_min');\n }\n\n /**\n * Get the maximum deal value of the automated report.\n *\n * @return int|null\n */\n public function getDealValueMax(): ?int\n {\n return $this->getAttribute('deal_value_max');\n }\n\n /**\n * Get the call types of the automated report.\n *\n * @return array\n */\n public function getCallTypes(): array\n {\n return $this->getAttribute('call_types') ?? [];\n }\n\n public function getMediaTypes(): array\n {\n return $this->getAttribute('media_types') ?? [];\n }\n\n /**\n * Get the minimum call duration of the automated report.\n *\n * @return int|null\n */\n public function getCallDurationMin(): ?int\n {\n return $this->getAttribute('call_duration_min');\n }\n\n /**\n * Get the maximum call duration of the automated report.\n *\n * @return int|null\n */\n public function getCallDurationMax(): ?int\n {\n return $this->getAttribute('call_duration_max');\n }\n\n /**\n * Get the groups of the automated report.\n *\n * @return array\n */\n public function getGroups(): array\n {\n return $this->getAttribute('groups') ?? [];\n }\n\n /**\n * Get the playbook categories of the automated report.\n *\n * @return array\n */\n public function getPlaybookCategories(): array\n {\n return $this->getAttribute('playbook_categories') ?? [];\n }\n\n /**\n * Get the deal at call stages of the automated report.\n *\n * @return array\n */\n public function getDealAtCallStages(): array\n {\n return $this->getAttribute('deal_at_call_stages') ?? [];\n }\n\n /**\n * Get the current deal stages of the automated report.\n *\n * @return array\n */\n public function getCurrentDealStages(): array\n {\n return $this->getAttribute('current_deal_stages') ?? [];\n }\n\n /**\n * Get the recipients of the automated report.\n *\n * @return array\n */\n public function getRecipients(): array\n {\n return $this->getAttribute('recipients') ?? [];\n }\n\n /**\n * Get the Jiminny's recipients of the automated report.\n *\n * @return array\n */\n public function getJiminnyRecipients(): array\n {\n return $this->getAttribute('jiminny_recipients') ?? [];\n }\n\n /**\n * Get the additional prompt input of the automated report.\n *\n * @return string|null\n */\n public function getAdditionalPromptInput(): ?string\n {\n return $this->getAttribute('additional_prompt_input');\n }\n\n public function getCustomName(): ?string\n {\n return $this->getAttribute('custom_name');\n }\n\n /**\n * Get the created at date of the automated report.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Get the deleted at date of the automated report.\n *\n * @return Carbon|null\n */\n public function getDeletedAt(): ?Carbon\n {\n return $this->getAttribute('deleted_at');\n }\n\n public function getTeam(): Team\n {\n return $this->getAttribute('team');\n }\n\n public function getCreator(): ?User\n {\n return $this->getAttribute('creator');\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Models;\n\nuse Illuminate\\Database\\Eloquent\\Model;\nuse Illuminate\\Database\\Eloquent\\Relations\\BelongsTo;\nuse Illuminate\\Database\\Eloquent\\SoftDeletes;\nuse Illuminate\\Support\\Carbon;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\AskAnything\\AskAnythingPrompt;\nuse Jiminny\\Services\\Kiosk\\AutomatedReports\\AutomatedReportsService;\nuse Jiminny\\Traits\\RequiresUUID;\n\n/**\n * Jiminny\\Models\\AutomatedReport\n *\n * @property int $id\n * @property string $uuid\n * @property int $team_id\n * @property string $type\n * @property bool $status\n * @property string $frequency\n * @property Carbon|null $from\n * @property Carbon|null $to\n * @property int|null $deal_value_min\n * @property int|null $deal_value_max\n * @property array $call_types\n * @property array $media_types\n * @property int|null $call_duration_min\n * @property int|null $call_duration_max\n * @property array|null $groups\n * @property array|null $playbook_categories\n * @property array|null $deal_at_call_stages\n * @property array|null $current_deal_stages\n * @property array $recipients\n * @property string|null $additional_prompt_input\n * @property string|null $custom_name\n * @property int|null $activity_search_id\n * @property int|null $ask_anything_prompt_id\n * @property Carbon|null $expires_at\n * @property Carbon|null $created_at\n * @property Carbon|null $updated_at\n * @property Carbon|null $deleted_at\n * @property-read \\Jiminny\\Models\\Team $team\n * @property-read \\Jiminny\\Models\\Activity\\Search|null $savedSearch\n * @property-read \\Jiminny\\Models\\AskAnything\\AskAnythingPrompt|null $askAnythingPrompt\n */\nclass AutomatedReport extends Model\n{\n use RequiresUUID;\n use SoftDeletes;\n\n protected $table = 'automated_reports';\n\n /**\n * The attributes that are mass assignable.\n *\n * @var array<int, string>\n */\n protected $fillable = [\n 'team_id',\n 'type',\n 'status',\n 'frequency',\n 'from',\n 'to',\n 'deal_value_min',\n 'deal_value_max',\n 'call_types',\n 'media_types',\n 'call_duration_min',\n 'call_duration_max',\n 'groups',\n 'playbook_categories',\n 'deal_at_call_stages',\n 'current_deal_stages',\n 'recipients',\n 'jiminny_recipients',\n 'additional_prompt_input',\n 'custom_name',\n 'created_by',\n 'activity_search_id',\n 'ask_anything_prompt_id',\n 'expires_at',\n ];\n\n protected $hidden = ['uuid'];\n\n /**\n * Get the attributes that should be cast.\n *\n * @return array<string, string>\n */\n protected function casts(): array\n {\n return [\n 'status' => 'boolean',\n 'from' => 'datetime',\n 'to' => 'datetime',\n 'call_types' => 'array',\n 'media_types' => 'array',\n 'groups' => 'array',\n 'playbook_categories' => 'array',\n 'deal_at_call_stages' => 'array',\n 'current_deal_stages' => 'array',\n 'recipients' => 'array',\n 'jiminny_recipients' => 'array',\n 'expires_at' => 'date',\n 'deleted_at' => 'datetime',\n ];\n }\n\n /**\n * Get the team that owns the automated report.\n */\n public function team()\n {\n return $this->belongsTo(Team::class);\n }\n\n /**\n *\n * Get the user who created the report.\n */\n public function creator(): BelongsTo\n {\n return $this->belongsTo(User::class, 'created_by');\n }\n\n public function savedSearch(): BelongsTo\n {\n return $this->belongsTo(Search::class, 'activity_search_id');\n }\n\n public function askAnythingPrompt(): BelongsTo\n {\n return $this->belongsTo(AskAnythingPrompt::class, 'ask_anything_prompt_id');\n }\n\n public function isAskJiminnyReport(): bool\n {\n return $this->getType() === AutomatedReportsService::TYPE_ASK_JIMINNY;\n }\n\n public function isExpired(): bool\n {\n $expiresAt = $this->getExpiresAt();\n\n return $expiresAt !== null && $expiresAt->isPast();\n }\n\n public function canExecute(): bool\n {\n if ($this->isAskJiminnyReport()) {\n return $this->getActivitySearchId() !== null\n && $this->getAskAnythingPromptId() !== null;\n }\n\n return true;\n }\n\n public function getActivitySearchId(): ?int\n {\n return $this->getAttribute('activity_search_id');\n }\n\n public function getAskAnythingPromptId(): ?int\n {\n return $this->getAttribute('ask_anything_prompt_id');\n }\n\n public function getExpiresAt(): ?Carbon\n {\n return $this->getAttribute('expires_at');\n }\n\n public function getSavedSearch(): ?Search\n {\n return $this->getAttribute('savedSearch');\n }\n\n public function getAskAnythingPrompt(): ?AskAnythingPrompt\n {\n return $this->getAttribute('askAnythingPrompt');\n }\n\n /**\n * Get the ID of the automated report.\n *\n * @return int\n */\n public function getId(): int\n {\n return $this->getAttribute('id');\n }\n\n /**\n * Get the UUID of the automated report.\n *\n * @return string\n */\n public function getUuid(): string\n {\n return $this->getAttribute('id_string');\n }\n\n /**\n * Get the team ID of the automated report.\n *\n * @return int\n */\n public function getTeamId(): int\n {\n return $this->getAttribute('team_id');\n }\n\n /**\n * Get the type of the automated report.\n *\n * @return string\n */\n public function getType(): string\n {\n return $this->getAttribute('type');\n }\n\n /**\n * Get the status of the automated report.\n * True means active, false means inactive.\n *\n * @return bool\n */\n public function getStatus(): bool\n {\n return $this->getAttribute('status');\n }\n\n /**\n * Get the frequency of the automated report.\n *\n * @return string\n */\n public function getFrequency(): string\n {\n return $this->getAttribute('frequency');\n }\n\n /**\n * Get the from date of the automated report.\n *\n * @return Carbon|null\n */\n public function getFrom(): ?Carbon\n {\n return $this->getAttribute('from');\n }\n\n /**\n * Get the to date of the automated report.\n *\n * @return Carbon|null\n */\n public function getTo(): ?Carbon\n {\n return $this->getAttribute('to');\n }\n\n /**\n * Get the minimum deal value of the automated report.\n *\n * @return int|null\n */\n public function getDealValueMin(): ?int\n {\n return $this->getAttribute('deal_value_min');\n }\n\n /**\n * Get the maximum deal value of the automated report.\n *\n * @return int|null\n */\n public function getDealValueMax(): ?int\n {\n return $this->getAttribute('deal_value_max');\n }\n\n /**\n * Get the call types of the automated report.\n *\n * @return array\n */\n public function getCallTypes(): array\n {\n return $this->getAttribute('call_types') ?? [];\n }\n\n public function getMediaTypes(): array\n {\n return $this->getAttribute('media_types') ?? [];\n }\n\n /**\n * Get the minimum call duration of the automated report.\n *\n * @return int|null\n */\n public function getCallDurationMin(): ?int\n {\n return $this->getAttribute('call_duration_min');\n }\n\n /**\n * Get the maximum call duration of the automated report.\n *\n * @return int|null\n */\n public function getCallDurationMax(): ?int\n {\n return $this->getAttribute('call_duration_max');\n }\n\n /**\n * Get the groups of the automated report.\n *\n * @return array\n */\n public function getGroups(): array\n {\n return $this->getAttribute('groups') ?? [];\n }\n\n /**\n * Get the playbook categories of the automated report.\n *\n * @return array\n */\n public function getPlaybookCategories(): array\n {\n return $this->getAttribute('playbook_categories') ?? [];\n }\n\n /**\n * Get the deal at call stages of the automated report.\n *\n * @return array\n */\n public function getDealAtCallStages(): array\n {\n return $this->getAttribute('deal_at_call_stages') ?? [];\n }\n\n /**\n * Get the current deal stages of the automated report.\n *\n * @return array\n */\n public function getCurrentDealStages(): array\n {\n return $this->getAttribute('current_deal_stages') ?? [];\n }\n\n /**\n * Get the recipients of the automated report.\n *\n * @return array\n */\n public function getRecipients(): array\n {\n return $this->getAttribute('recipients') ?? [];\n }\n\n /**\n * Get the Jiminny's recipients of the automated report.\n *\n * @return array\n */\n public function getJiminnyRecipients(): array\n {\n return $this->getAttribute('jiminny_recipients') ?? [];\n }\n\n /**\n * Get the additional prompt input of the automated report.\n *\n * @return string|null\n */\n public function getAdditionalPromptInput(): ?string\n {\n return $this->getAttribute('additional_prompt_input');\n }\n\n public function getCustomName(): ?string\n {\n return $this->getAttribute('custom_name');\n }\n\n /**\n * Get the created at date of the automated report.\n *\n * @return Carbon\n */\n public function getCreatedAt(): Carbon\n {\n return $this->getAttribute('created_at');\n }\n\n /**\n * Get the updated at date of the automated report.\n *\n * @return Carbon\n */\n public function getUpdatedAt(): Carbon\n {\n return $this->getAttribute('updated_at');\n }\n\n /**\n * Get the deleted at date of the automated report.\n *\n * @return Carbon|null\n */\n public function getDeletedAt(): ?Carbon\n {\n return $this->getAttribute('deleted_at');\n }\n\n public function getTeam(): Team\n {\n return $this->getAttribute('team');\n }\n\n public function getCreator(): ?User\n {\n return $this->getAttribute('creator');\n }\n}","role_description":"text entry area","is_enabled":true,"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":"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":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.02013889,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXButton","text":"Previous Highlighted Error","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.025555555},"on_screen":false,"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.0,"top":0.0,"width":0.014583333,"height":0.025555555},"on_screen":false,"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\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v1\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v1\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v1\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v1\\Api\\DealsApi;\nuse Pipedrive\\versions\\v1\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v1\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v1\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // Official SDK uses getDealsSummary instead of getDeals\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // Official SDK has different method names - test instantiation works\n // The actual method names differ from community SDK\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"PersonsApi client instantiated successfully in {$elapsed}ms - method mapping required\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // Official SDK has different method names - test instantiation works\n // The actual method names differ from community SDK\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"ActivitiesApi client instantiated successfully in {$elapsed}ms - method mapping required\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\n }\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\ndeclare(strict_types=1);\n\nnamespace Jiminny\\Console\\Commands\\Crm;\n\nuse Carbon\\Carbon;\nuse Exception;\nuse Illuminate\\Console\\Command;\nuse Jiminny\\Component\\Encryption\\EncryptedTokenManager;\nuse Jiminny\\Models\\SocialAccount;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\User;\nuse Pipedrive\\versions\\v1\\Api\\ActivitiesApi;\nuse Pipedrive\\versions\\v1\\Api\\ActivityFieldsApi;\nuse Pipedrive\\versions\\v1\\Api\\DealFieldsApi;\nuse Pipedrive\\versions\\v1\\Api\\DealsApi;\nuse Pipedrive\\versions\\v1\\Api\\PersonFieldsApi;\nuse Pipedrive\\versions\\v1\\Api\\PersonsApi;\nuse Pipedrive\\versions\\v1\\Configuration;\n\nclass TestPipedriveOfficialSdkCommand extends Command\n{\n protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';\n\n protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';\n\n private array $results = [];\n\n private EncryptedTokenManager $tokenManager;\n\n public function __construct(EncryptedTokenManager $tokenManager)\n {\n parent::__construct();\n $this->tokenManager = $tokenManager;\n }\n\n public function handle(): int\n {\n $teamId = (int) $this->argument('teamId');\n\n $this->info(\"Starting Pipedrive Official SDK POC for Team ID: {$teamId}\");\n $this->newLine();\n\n try {\n $this->runTests($teamId);\n } catch (Exception $e) {\n $this->error(\"POC failed with error: {$e->getMessage()}\");\n $this->error($e->getTraceAsString());\n\n return 1;\n }\n\n $this->displayResults();\n\n return 0;\n }\n\n private function runTests(int $teamId): void\n {\n $team = Team::find($teamId);\n if (! $team) {\n throw new Exception(\"Team with ID {$teamId} not found\");\n }\n\n $socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)\n ->whereHas('sociable', function ($query) use ($team) {\n $query->where('team_id', $team->id);\n })\n ->orderByDesc('expires') // Get the most recently expiring token\n ->first();\n\n if (! $socialAccount) {\n throw new Exception(\"No Pipedrive social account found for team {$teamId}\");\n }\n\n $this->info(\"Found Pipedrive account for team: {$team->name}\");\n $this->newLine();\n\n // Test 1: OAuth Initialization\n $this->testOAuthInitialization($socialAccount);\n\n // Test 2: Basic CRUD Operations\n $this->testBasicCrudOperations($socialAccount);\n\n // Test 3: Field Metadata\n $this->testFieldMetadata($socialAccount);\n\n // Test 4: v2 API Support\n $this->testV2ApiSupport($socialAccount);\n\n // Test 5: Error Handling\n $this->testErrorHandling($socialAccount);\n }\n\n private function testOAuthInitialization(SocialAccount $socialAccount): void\n {\n $this->info('Test 1: OAuth Initialization');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $client = new DealsApi(null, $config);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', true, \"Client initialized successfully in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);\n }\n\n $this->newLine();\n }\n\n private function testBasicCrudOperations(SocialAccount $socialAccount): void\n {\n $this->info('Test 2: Basic CRUD Operations');\n\n try {\n // Get the raw token from database\n $rawDbToken = $socialAccount->getProviderUserToken();\n $this->info(\"DB token (length: \" . strlen($rawDbToken) . \")\");\n $this->info(\"DB token preview: \" . substr($rawDbToken, 0, 20) . \"...\");\n\n // Check token expiry\n $expires = $socialAccount->expires;\n $this->info(\"Token expires at: \" . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));\n $this->info(\"Token is expired: \" . ($expires && $expires < time() ? 'YES' : 'NO'));\n\n // Test with the DB token directly\n $this->info(\"\\n--- Testing with DB token ---\");\n $config = new Configuration();\n $config->setAccessToken($rawDbToken);\n\n // Test 2a: Get Deals Summary\n $this->testGetDeals($config);\n\n // Test 2b: Get Persons\n $this->testGetPersons($config);\n\n // Test 2c: Get Activities\n $this->testGetActivities($config);\n } catch (Exception $e) {\n $this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testCurrentSystemApproach(SocialAccount $socialAccount): void\n {\n $startTime = microtime(true);\n\n try {\n // Simulate how current system makes requests\n $token = $socialAccount->getProviderUserToken();\n $url = 'https://api.pipedrive.com/api/v2/deals';\n\n $headers = [\n 'Authorization' => 'Bearer ' . $token,\n 'Accept' => 'application/json',\n ];\n\n $client = new \\GuzzleHttp\\Client();\n $response = $client->get($url, [\n 'headers' => $headers,\n 'timeout' => 30,\n ]);\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $statusCode = $response->getStatusCode();\n $this->recordResult('Current System v2 API', $statusCode === 200, \"Status: {$statusCode} in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetDeals(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealsApi(null, $config);\n // Official SDK uses getDealsSummary instead of getDeals\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', true, \"Retrieved deals summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deals Summary', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersons(Configuration $config): void\n {\n $this->info('Test 2b: Get Persons');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonsApi(null, $config);\n // Official SDK has different method names - test instantiation works\n // The actual method names differ from community SDK\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', true, \"PersonsApi client instantiated successfully in {$elapsed}ms - method mapping required\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivities(Configuration $config): void\n {\n $this->info('Test 2c: Get Activities');\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivitiesApi(null, $config);\n // Official SDK has different method names - test instantiation works\n // The actual method names differ from community SDK\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', true, \"ActivitiesApi client instantiated successfully in {$elapsed}ms - method mapping required\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testFieldMetadata(SocialAccount $socialAccount): void\n {\n $this->info('Test 3: Field Metadata');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n // Test 3a: Get Deal Fields\n $this->testGetDealFields($config);\n\n // Test 3b: Get Person Fields\n $this->testGetPersonFields($config);\n\n // Test 3c: Get Activity Fields\n $this->testGetActivityFields($config);\n } catch (Exception $e) {\n $this->recordResult('Field Metadata', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testGetDealFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new DealFieldsApi(null, $config);\n $result = $apiInstance->getDealFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Deal Fields', true, \"Retrieved {$count} deal fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetPersonFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new PersonFieldsApi(null, $config);\n $result = $apiInstance->getPersonFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Person Fields', true, \"Retrieved {$count} person fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testGetActivityFields(Configuration $config): void\n {\n $startTime = microtime(true);\n\n try {\n $apiInstance = new ActivityFieldsApi(null, $config);\n $result = $apiInstance->getActivityFields();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $count = $result->getData() ? count($result->getData()) : 0;\n $this->recordResult('Get Activity Fields', true, \"Retrieved {$count} activity fields in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function testV2ApiSupport(SocialAccount $socialAccount): void\n {\n $this->info('Test 4: v2 API Support (Cursor-based Pagination)');\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n\n $startTime = microtime(true);\n\n // Test v2 deals endpoint with cursor pagination\n // Note: The official SDK may or may not have v2 API support\n // This test will determine if v2 is available\n try {\n $apiInstance = new DealsApi(null, $config);\n $updatedSince = Carbon::now()->subDays(30)->toRfc3339String();\n $result = $apiInstance->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n\n // Check if response has cursor information (v2 indicator)\n // The response object doesn't have getAdditionalData method\n // Just test if the call works - v2 API support is limited in official SDK v1\n $this->recordResult('v2 API Support', false, \"v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);\n }\n } catch (Exception $e) {\n $this->recordResult('v2 API Support', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testErrorHandling(SocialAccount $socialAccount): void\n {\n $this->info('Test 5: Error Handling');\n\n try {\n // Test 5a: Invalid Token\n $this->testInvalidToken();\n\n // Test 5b: Non-existent Resource\n $this->testNonExistentResource($socialAccount);\n } catch (Exception $e) {\n $this->recordResult('Error Handling', false, $e->getMessage(), 0);\n }\n\n $this->newLine();\n }\n\n private function testInvalidToken(): void\n {\n $this->info('Test 5a: Invalid Token');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken('invalid_token');\n $client = new DealsApi(null, $config);\n\n $client->getDealsSummary();\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Invalid Token Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n }\n\n private function testNonExistentResource(SocialAccount $socialAccount): void\n {\n $this->info('Test 5b: Non-existent Resource');\n $startTime = microtime(true);\n\n try {\n $config = new Configuration();\n $config->setAccessToken($socialAccount->provider_user_token);\n $client = new DealsApi(null, $config);\n\n // Try to get a deal with a very high ID that likely doesn't exist\n // Official SDK has getDealsSummary which works without specific ID\n // Instead, let's test with an invalid field ID\n try {\n $fieldClient = new DealFieldsApi(null, $config);\n $fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist\n\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, \"Expected error but request succeeded in {$elapsed}ms\", $elapsed);\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', true, \"Correctly threw exception: {$e->getMessage()} in {$elapsed}ms\", $elapsed);\n }\n } catch (Exception $e) {\n $elapsed = round((microtime(true) - $startTime) * 1000, 2);\n $this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);\n }\n }\n\n private function recordResult(string $testName, bool $success, string $message, float $elapsed): void\n {\n $this->results[] = [\n 'test' => $testName,\n 'success' => $success,\n 'message' => $message,\n 'elapsed' => $elapsed,\n ];\n\n $status = $success ? '✅ PASS' : '❌ FAIL';\n $this->line(\" {$status} - {$testName}: {$message}\");\n }\n\n private function displayResults(): void\n {\n $this->newLine();\n $this->info('=== POC Test Results Summary ===');\n $this->newLine();\n\n $total = count($this->results);\n $passed = count(array_filter($this->results, fn ($r) => $r['success']));\n $failed = $total - $passed;\n\n $this->line(\"Total Tests: {$total}\");\n $this->line(\"Passed: {$passed}\");\n $this->line(\"Failed: {$failed}\");\n $this->newLine();\n\n $totalTime = array_sum(array_column($this->results, 'elapsed'));\n $this->line(\"Total Execution Time: {$totalTime}ms\");\n $this->newLine();\n\n if ($failed > 0) {\n $this->warn('Failed Tests:');\n foreach ($this->results as $result) {\n if (! $result['success']) {\n $this->line(\" - {$result['test']}: {$result['message']}\");\n }\n }\n $this->newLine();\n }\n\n $this->info('=== Detailed Results ===');\n foreach ($this->results as $result) {\n $status = $result['success'] ? '✅' : '❌';\n $this->line(\"{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}\");\n }\n\n $this->newLine();\n $this->info('=== Recommendations ===');\n\n if ($passed === $total) {\n $this->info('✅ All tests passed! The official SDK is viable for migration.');\n $this->info('Next steps: Proceed with full migration planning.');\n } else {\n $this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');\n $this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');\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}]...
|
2016543674200853130
|
52717014917466756
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, 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
6
1
6
Previous Highlighted Error
Next Highlighted Error
<?php
namespace Jiminny\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\AskAnything\AskAnythingPrompt;
use Jiminny\Services\Kiosk\AutomatedReports\AutomatedReportsService;
use Jiminny\Traits\RequiresUUID;
/**
* Jiminny\Models\AutomatedReport
*
* @property int $id
* @property string $uuid
* @property int $team_id
* @property string $type
* @property bool $status
* @property string $frequency
* @property Carbon|null $from
* @property Carbon|null $to
* @property int|null $deal_value_min
* @property int|null $deal_value_max
* @property array $call_types
* @property array $media_types
* @property int|null $call_duration_min
* @property int|null $call_duration_max
* @property array|null $groups
* @property array|null $playbook_categories
* @property array|null $deal_at_call_stages
* @property array|null $current_deal_stages
* @property array $recipients
* @property string|null $additional_prompt_input
* @property string|null $custom_name
* @property int|null $activity_search_id
* @property int|null $ask_anything_prompt_id
* @property Carbon|null $expires_at
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
* @property Carbon|null $deleted_at
* @property-read \Jiminny\Models\Team $team
* @property-read \Jiminny\Models\Activity\Search|null $savedSearch
* @property-read \Jiminny\Models\AskAnything\AskAnythingPrompt|null $askAnythingPrompt
*/
class AutomatedReport extends Model
{
use RequiresUUID;
use SoftDeletes;
protected $table = 'automated_reports';
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'team_id',
'type',
'status',
'frequency',
'from',
'to',
'deal_value_min',
'deal_value_max',
'call_types',
'media_types',
'call_duration_min',
'call_duration_max',
'groups',
'playbook_categories',
'deal_at_call_stages',
'current_deal_stages',
'recipients',
'jiminny_recipients',
'additional_prompt_input',
'custom_name',
'created_by',
'activity_search_id',
'ask_anything_prompt_id',
'expires_at',
];
protected $hidden = ['uuid'];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'status' => 'boolean',
'from' => 'datetime',
'to' => 'datetime',
'call_types' => 'array',
'media_types' => 'array',
'groups' => 'array',
'playbook_categories' => 'array',
'deal_at_call_stages' => 'array',
'current_deal_stages' => 'array',
'recipients' => 'array',
'jiminny_recipients' => 'array',
'expires_at' => 'date',
'deleted_at' => 'datetime',
];
}
/**
* Get the team that owns the automated report.
*/
public function team()
{
return $this->belongsTo(Team::class);
}
/**
*
* Get the user who created the report.
*/
public function creator(): BelongsTo
{
return $this->belongsTo(User::class, 'created_by');
}
public function savedSearch(): BelongsTo
{
return $this->belongsTo(Search::class, 'activity_search_id');
}
public function askAnythingPrompt(): BelongsTo
{
return $this->belongsTo(AskAnythingPrompt::class, 'ask_anything_prompt_id');
}
public function isAskJiminnyReport(): bool
{
return $this->getType() === AutomatedReportsService::TYPE_ASK_JIMINNY;
}
public function isExpired(): bool
{
$expiresAt = $this->getExpiresAt();
return $expiresAt !== null && $expiresAt->isPast();
}
public function canExecute(): bool
{
if ($this->isAskJiminnyReport()) {
return $this->getActivitySearchId() !== null
&& $this->getAskAnythingPromptId() !== null;
}
return true;
}
public function getActivitySearchId(): ?int
{
return $this->getAttribute('activity_search_id');
}
public function getAskAnythingPromptId(): ?int
{
return $this->getAttribute('ask_anything_prompt_id');
}
public function getExpiresAt(): ?Carbon
{
return $this->getAttribute('expires_at');
}
public function getSavedSearch(): ?Search
{
return $this->getAttribute('savedSearch');
}
public function getAskAnythingPrompt(): ?AskAnythingPrompt
{
return $this->getAttribute('askAnythingPrompt');
}
/**
* Get the ID of the automated report.
*
* @return int
*/
public function getId(): int
{
return $this->getAttribute('id');
}
/**
* Get the UUID of the automated report.
*
* @return string
*/
public function getUuid(): string
{
return $this->getAttribute('id_string');
}
/**
* Get the team ID of the automated report.
*
* @return int
*/
public function getTeamId(): int
{
return $this->getAttribute('team_id');
}
/**
* Get the type of the automated report.
*
* @return string
*/
public function getType(): string
{
return $this->getAttribute('type');
}
/**
* Get the status of the automated report.
* True means active, false means inactive.
*
* @return bool
*/
public function getStatus(): bool
{
return $this->getAttribute('status');
}
/**
* Get the frequency of the automated report.
*
* @return string
*/
public function getFrequency(): string
{
return $this->getAttribute('frequency');
}
/**
* Get the from date of the automated report.
*
* @return Carbon|null
*/
public function getFrom(): ?Carbon
{
return $this->getAttribute('from');
}
/**
* Get the to date of the automated report.
*
* @return Carbon|null
*/
public function getTo(): ?Carbon
{
return $this->getAttribute('to');
}
/**
* Get the minimum deal value of the automated report.
*
* @return int|null
*/
public function getDealValueMin(): ?int
{
return $this->getAttribute('deal_value_min');
}
/**
* Get the maximum deal value of the automated report.
*
* @return int|null
*/
public function getDealValueMax(): ?int
{
return $this->getAttribute('deal_value_max');
}
/**
* Get the call types of the automated report.
*
* @return array
*/
public function getCallTypes(): array
{
return $this->getAttribute('call_types') ?? [];
}
public function getMediaTypes(): array
{
return $this->getAttribute('media_types') ?? [];
}
/**
* Get the minimum call duration of the automated report.
*
* @return int|null
*/
public function getCallDurationMin(): ?int
{
return $this->getAttribute('call_duration_min');
}
/**
* Get the maximum call duration of the automated report.
*
* @return int|null
*/
public function getCallDurationMax(): ?int
{
return $this->getAttribute('call_duration_max');
}
/**
* Get the groups of the automated report.
*
* @return array
*/
public function getGroups(): array
{
return $this->getAttribute('groups') ?? [];
}
/**
* Get the playbook categories of the automated report.
*
* @return array
*/
public function getPlaybookCategories(): array
{
return $this->getAttribute('playbook_categories') ?? [];
}
/**
* Get the deal at call stages of the automated report.
*
* @return array
*/
public function getDealAtCallStages(): array
{
return $this->getAttribute('deal_at_call_stages') ?? [];
}
/**
* Get the current deal stages of the automated report.
*
* @return array
*/
public function getCurrentDealStages(): array
{
return $this->getAttribute('current_deal_stages') ?? [];
}
/**
* Get the recipients of the automated report.
*
* @return array
*/
public function getRecipients(): array
{
return $this->getAttribute('recipients') ?? [];
}
/**
* Get the Jiminny's recipients of the automated report.
*
* @return array
*/
public function getJiminnyRecipients(): array
{
return $this->getAttribute('jiminny_recipients') ?? [];
}
/**
* Get the additional prompt input of the automated report.
*
* @return string|null
*/
public function getAdditionalPromptInput(): ?string
{
return $this->getAttribute('additional_prompt_input');
}
public function getCustomName(): ?string
{
return $this->getAttribute('custom_name');
}
/**
* Get the created at date of the automated report.
*
* @return Carbon
*/
public function getCreatedAt(): Carbon
{
return $this->getAttribute('created_at');
}
/**
* Get the updated at date of the automated report.
*
* @return Carbon
*/
public function getUpdatedAt(): Carbon
{
return $this->getAttribute('updated_at');
}
/**
* Get the deleted at date of the automated report.
*
* @return Carbon|null
*/
public function getDeletedAt(): ?Carbon
{
return $this->getAttribute('deleted_at');
}
public function getTeam(): Team
{
return $this->getAttribute('team');
}
public function getCreator(): ?User
{
return $this->getAttribute('creator');
}
}
Code changed:
Hide
Sync Changes
Hide This Notification
1
51
1
Previous Highlighted Error
Next Highlighted Error
<?php
declare(strict_types=1);
namespace Jiminny\Console\Commands\Crm;
use Carbon\Carbon;
use Exception;
use Illuminate\Console\Command;
use Jiminny\Component\Encryption\EncryptedTokenManager;
use Jiminny\Models\SocialAccount;
use Jiminny\Models\Team;
use Jiminny\Models\User;
use Pipedrive\versions\v1\Api\ActivitiesApi;
use Pipedrive\versions\v1\Api\ActivityFieldsApi;
use Pipedrive\versions\v1\Api\DealFieldsApi;
use Pipedrive\versions\v1\Api\DealsApi;
use Pipedrive\versions\v1\Api\PersonFieldsApi;
use Pipedrive\versions\v1\Api\PersonsApi;
use Pipedrive\versions\v1\Configuration;
class TestPipedriveOfficialSdkCommand extends Command
{
protected $signature = 'jiminny:test-pipedrive-official-sdk {teamId}';
protected $description = 'Test official Pipedrive SDK (pipedrive/pipedrive) with existing OAuth tokens';
private array $results = [];
private EncryptedTokenManager $tokenManager;
public function __construct(EncryptedTokenManager $tokenManager)
{
parent::__construct();
$this->tokenManager = $tokenManager;
}
public function handle(): int
{
$teamId = (int) $this->argument('teamId');
$this->info("Starting Pipedrive Official SDK POC for Team ID: {$teamId}");
$this->newLine();
try {
$this->runTests($teamId);
} catch (Exception $e) {
$this->error("POC failed with error: {$e->getMessage()}");
$this->error($e->getTraceAsString());
return 1;
}
$this->displayResults();
return 0;
}
private function runTests(int $teamId): void
{
$team = Team::find($teamId);
if (! $team) {
throw new Exception("Team with ID {$teamId} not found");
}
$socialAccount = SocialAccount::where('provider', SocialAccount::PROVIDER_PIPEDRIVE)
->whereHas('sociable', function ($query) use ($team) {
$query->where('team_id', $team->id);
})
->orderByDesc('expires') // Get the most recently expiring token
->first();
if (! $socialAccount) {
throw new Exception("No Pipedrive social account found for team {$teamId}");
}
$this->info("Found Pipedrive account for team: {$team->name}");
$this->newLine();
// Test 1: OAuth Initialization
$this->testOAuthInitialization($socialAccount);
// Test 2: Basic CRUD Operations
$this->testBasicCrudOperations($socialAccount);
// Test 3: Field Metadata
$this->testFieldMetadata($socialAccount);
// Test 4: v2 API Support
$this->testV2ApiSupport($socialAccount);
// Test 5: Error Handling
$this->testErrorHandling($socialAccount);
}
private function testOAuthInitialization(SocialAccount $socialAccount): void
{
$this->info('Test 1: OAuth Initialization');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', true, "Client initialized successfully in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('OAuth Initialization', false, $e->getMessage(), $elapsed);
}
$this->newLine();
}
private function testBasicCrudOperations(SocialAccount $socialAccount): void
{
$this->info('Test 2: Basic CRUD Operations');
try {
// Get the raw token from database
$rawDbToken = $socialAccount->getProviderUserToken();
$this->info("DB token (length: " . strlen($rawDbToken) . ")");
$this->info("DB token preview: " . substr($rawDbToken, 0, 20) . "...");
// Check token expiry
$expires = $socialAccount->expires;
$this->info("Token expires at: " . ($expires ? Carbon::createFromTimestamp($expires)->toDateTimeString() : 'null'));
$this->info("Token is expired: " . ($expires && $expires < time() ? 'YES' : 'NO'));
// Test with the DB token directly
$this->info("\n--- Testing with DB token ---");
$config = new Configuration();
$config->setAccessToken($rawDbToken);
// Test 2a: Get Deals Summary
$this->testGetDeals($config);
// Test 2b: Get Persons
$this->testGetPersons($config);
// Test 2c: Get Activities
$this->testGetActivities($config);
} catch (Exception $e) {
$this->recordResult('Basic CRUD Operations', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testCurrentSystemApproach(SocialAccount $socialAccount): void
{
$startTime = microtime(true);
try {
// Simulate how current system makes requests
$token = $socialAccount->getProviderUserToken();
$url = 'https://api.pipedrive.com/api/v2/deals';
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$client = new \GuzzleHttp\Client();
$response = $client->get($url, [
'headers' => $headers,
'timeout' => 30,
]);
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$statusCode = $response->getStatusCode();
$this->recordResult('Current System v2 API', $statusCode === 200, "Status: {$statusCode} in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Current System v2 API', false, $e->getMessage(), $elapsed);
}
}
private function testGetDeals(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealsApi(null, $config);
// Official SDK uses getDealsSummary instead of getDeals
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', true, "Retrieved deals summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deals Summary', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersons(Configuration $config): void
{
$this->info('Test 2b: Get Persons');
$startTime = microtime(true);
try {
$apiInstance = new PersonsApi(null, $config);
// Official SDK has different method names - test instantiation works
// The actual method names differ from community SDK
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', true, "PersonsApi client instantiated successfully in {$elapsed}ms - method mapping required", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Persons', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivities(Configuration $config): void
{
$this->info('Test 2c: Get Activities');
$startTime = microtime(true);
try {
$apiInstance = new ActivitiesApi(null, $config);
// Official SDK has different method names - test instantiation works
// The actual method names differ from community SDK
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', true, "ActivitiesApi client instantiated successfully in {$elapsed}ms - method mapping required", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activities', false, $e->getMessage(), $elapsed);
}
}
private function testFieldMetadata(SocialAccount $socialAccount): void
{
$this->info('Test 3: Field Metadata');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
// Test 3a: Get Deal Fields
$this->testGetDealFields($config);
// Test 3b: Get Person Fields
$this->testGetPersonFields($config);
// Test 3c: Get Activity Fields
$this->testGetActivityFields($config);
} catch (Exception $e) {
$this->recordResult('Field Metadata', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testGetDealFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new DealFieldsApi(null, $config);
$result = $apiInstance->getDealFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Deal Fields', true, "Retrieved {$count} deal fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Deal Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetPersonFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new PersonFieldsApi(null, $config);
$result = $apiInstance->getPersonFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Person Fields', true, "Retrieved {$count} person fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Person Fields', false, $e->getMessage(), $elapsed);
}
}
private function testGetActivityFields(Configuration $config): void
{
$startTime = microtime(true);
try {
$apiInstance = new ActivityFieldsApi(null, $config);
$result = $apiInstance->getActivityFields();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$count = $result->getData() ? count($result->getData()) : 0;
$this->recordResult('Get Activity Fields', true, "Retrieved {$count} activity fields in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Get Activity Fields', false, $e->getMessage(), $elapsed);
}
}
private function testV2ApiSupport(SocialAccount $socialAccount): void
{
$this->info('Test 4: v2 API Support (Cursor-based Pagination)');
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$startTime = microtime(true);
// Test v2 deals endpoint with cursor pagination
// Note: The official SDK may or may not have v2 API support
// This test will determine if v2 is available
try {
$apiInstance = new DealsApi(null, $config);
$updatedSince = Carbon::now()->subDays(30)->toRfc3339String();
$result = $apiInstance->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
// Check if response has cursor information (v2 indicator)
// The response object doesn't have getAdditionalData method
// Just test if the call works - v2 API support is limited in official SDK v1
$this->recordResult('v2 API Support', false, "v1 API works but v2 cursor pagination not available in official SDK v1. Retrieved summary in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('v2 API Support', false, $e->getMessage(), $elapsed);
}
} catch (Exception $e) {
$this->recordResult('v2 API Support', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testErrorHandling(SocialAccount $socialAccount): void
{
$this->info('Test 5: Error Handling');
try {
// Test 5a: Invalid Token
$this->testInvalidToken();
// Test 5b: Non-existent Resource
$this->testNonExistentResource($socialAccount);
} catch (Exception $e) {
$this->recordResult('Error Handling', false, $e->getMessage(), 0);
}
$this->newLine();
}
private function testInvalidToken(): void
{
$this->info('Test 5a: Invalid Token');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken('invalid_token');
$client = new DealsApi(null, $config);
$client->getDealsSummary();
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Invalid Token Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
}
private function testNonExistentResource(SocialAccount $socialAccount): void
{
$this->info('Test 5b: Non-existent Resource');
$startTime = microtime(true);
try {
$config = new Configuration();
$config->setAccessToken($socialAccount->provider_user_token);
$client = new DealsApi(null, $config);
// Try to get a deal with a very high ID that likely doesn't exist
// Official SDK has getDealsSummary which works without specific ID
// Instead, let's test with an invalid field ID
try {
$fieldClient = new DealFieldsApi(null, $config);
$fieldClient->getDealField(999999999); // Very high ID that likely doesn't exist
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, "Expected error but request succeeded in {$elapsed}ms", $elapsed);
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', true, "Correctly threw exception: {$e->getMessage()} in {$elapsed}ms", $elapsed);
}
} catch (Exception $e) {
$elapsed = round((microtime(true) - $startTime) * 1000, 2);
$this->recordResult('Non-existent Resource Error', false, $e->getMessage(), $elapsed);
}
}
private function recordResult(string $testName, bool $success, string $message, float $elapsed): void
{
$this->results[] = [
'test' => $testName,
'success' => $success,
'message' => $message,
'elapsed' => $elapsed,
];
$status = $success ? '✅ PASS' : '❌ FAIL';
$this->line(" {$status} - {$testName}: {$message}");
}
private function displayResults(): void
{
$this->newLine();
$this->info('=== POC Test Results Summary ===');
$this->newLine();
$total = count($this->results);
$passed = count(array_filter($this->results, fn ($r) => $r['success']));
$failed = $total - $passed;
$this->line("Total Tests: {$total}");
$this->line("Passed: {$passed}");
$this->line("Failed: {$failed}");
$this->newLine();
$totalTime = array_sum(array_column($this->results, 'elapsed'));
$this->line("Total Execution Time: {$totalTime}ms");
$this->newLine();
if ($failed > 0) {
$this->warn('Failed Tests:');
foreach ($this->results as $result) {
if (! $result['success']) {
$this->line(" - {$result['test']}: {$result['message']}");
}
}
$this->newLine();
}
$this->info('=== Detailed Results ===');
foreach ($this->results as $result) {
$status = $result['success'] ? '✅' : '❌';
$this->line("{$status} {$result['test']} ({$result['elapsed']}ms): {$result['message']}");
}
$this->newLine();
$this->info('=== Recommendations ===');
if ($passed === $total) {
$this->info('✅ All tests passed! The official SDK is viable for migration.');
$this->info('Next steps: Proceed with full migration planning.');
} else {
$this->warn('⚠️ Some tests failed. Review the failures above before proceeding.');
$this->warn('Consider hybrid approach or investigate alternatives if critical operations fail.');
}
}
}
Project
Project
New File or Directory…
Expand Selected
Collapse All
Options
Hide...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49717
|
1767
|
0
|
2026-05-18T06:54:02.563630+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087242563_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 Prom( Ate x | E3 мо x() Sche x|© Curs x* Ca XCost Xoum x@vo xPipe xD Cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps07 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item, Add designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting CenterArchived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© JmC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% L28• Mon 18 May 9:54:02Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IVanovAneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik7:36Lộ3...
|
NULL
|
-3047487895851588803
|
NULL
|
click
|
ocr
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 Prom( Ate x | E3 мо x() Sche x|© Curs x* Ca XCost Xoum x@vo xPipe xD Cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps07 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item, Add designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting CenterArchived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© JmC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% L28• Mon 18 May 9:54:02Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IVanovAneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik7:36Lộ3...
|
49716
|
NULL
|
NULL
|
NULL
|
|
49718
|
NULL
|
0
|
2026-05-18T06:54:02.600637+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087242600_m2.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormVIewINavicareCodeLaravelKeractorFV faVsco. PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcache.pnp© SyncPlanhat.php©syncleammeradata.ong1estPlpeariveomricialsakcommand.or© createActivityAdded loPlaylistevent.pnpUpoateopponunityspecrications.onocreatePlaybookcreatedevent.ong>@ Dealinsights• … Dev>C Dialersc) IntearationApp/Service.php(C) LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC) CreateCommentedEvent.phpC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.phoC Elasticsearch(C)AskAnvthinaPromotService.oho(C)AutomatedReportsRepositorv.ohd› Enqagementstatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohoC) RequestGenerateReport.Job.oho/• Livestream(C) AutomatedReportkesulconp(C) AutomatedRenort nhn XMallboxesclass AutomatedRenont extends Modella Midrate46 y1Y6APlavbackithemes141return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:M PlavbooksPlaylists143> M Postmarkpublic function isExpired: boolf...}> M PronhetAv Reports© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.phtpublic function canExecute@: boolf...;public function getActivitvSearchido: ?int-...=(C) CroateMockAck.liminnvRenortResult@© DeleteReportCommand.php© GenerateMarketingReport.phppublic function getAskAnvthingPromptIdO: 2intf...}© Team.php© Usage.phpnublic function aetExoiresAto: 2Carhons...->07 Slack›_ TeamsServicesToC exOutputtid jiminny.social_accounts xv M Databasedid w 1 rowvvAEU#consolee idv&jiminny@localhost# HS localsociable 1dA SFA PRODW provider_user_id! provider_user_token« console(• provider refresh tokenA STAGINGI expires# console 2 s 241 msy, NoshorM refresh token expiresU oroviden!O state1 auth_scopeI retry afterI created atundated at1 row retrieved ctartina from 1 in 740 mc leyecution: 186 mc fetchina: 554 mgDally - Platrorm • now100% S2• Mon 18 May 9:54:02AskJiminnyReportActivityServiceTest v+0 ..=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU<:onodeclare(strict types=1)namespace Jiminny Console commands Crm:use carbon caroon:use Excentlonsuse iLLuminate Console Command:use Jiminny Comoonent EncrvotionEncrvotedtokenManager:use Jiminny Models\SocialAccount;use Jiminny Models Teamuse Jiminny Models \User,use Pipedrive\versions\v1\Api \ActivitiesApi;use Pipedrive\versions\v1\Api\ActivityFieldsApi;use Pipedrive\versions\v1\Api \DealFieldsApi;use Pipedrive\versions\v1\Api\DealsApi;use Pipedrive\versions\v1\Api \PersonFieldsApi;use Pipedrive verszons ve Apt rersonsapluse Pipedrive\versions\v1 \Configuration;22 Dclass lestPipedrive0fficialSdkcommand extends Commandl24 Cprotected ssiqnature = '71m1nny:test-p1pedrive-off1c1al-sak teamlor'n26 đprotected sdescription -AocesFoaCiX Pipednive Sok (papedrive /pipednive) wäth exitDebugging Pipedrive S•Get Person rielas. ogs.oms (/ Tielas)• Get Activity Fields: 1005.95ms (35 fields)Error Handling• Invalid Token Error: 1067.26ms (correctly throws 401)•Non-existent Resource Error: 796.42ms (correctly throws 404)Expected Failure (1/10)VZ APl suppon• V1 API works but v2 cursor pagination not available in official SDK v1• Solution: Use direct Hiitp calls tor v2 endooints or uoarade to Sok v2 when avallablelConclusionThe official Pipedrive SDK is viable for migration. The token format is compatible, core operations work correctly, and error handling functions properly. The main work will bes1. Method name mapping between community and official SDKs2. Response structure adaptation2. v2 APl imnlementation (direct HTTP calls or SDK unarado)Total execution time: 7.6 seconds2) Reject allAccept allwe should use v2 with new SDK. Are vou usina new SDK?+ &codeSWE.1G1116241.19555731|V1U:AQLBAHS -L2 TNK2yuuuaLq142hWb9crUNKTpk4=-109r5nXap_6AE0hDhDQVa1nvWCHEVnpVSEAAAAFB8BqKahk:G9WOBBwagbzBtAgEAMGgGCSqGS1D3D0EHATAeB9LghkgBZ0MEAS4wEQQMnG8KNCZLI5EnLRPXA9EQgDsGP1CKfI5MU/0eL36BtM5FCQa56mYUy24_AAoqdh2y;V=ka6egLqSOinp-5G4JE/frJURMV8VIW-FY149HGHSO8DKUSBq30JM398MH84Cb10mzCrXaVo2GbZEd6nn5034113:[TELEGRAM_TOKEN]b2bfc1779088398oinedriveconnectedibase.deals:full.activities:full.contacts:full,search:read2023-09-08 09:44:292026-05-15 15:44•31W Windsurf Toams137:1 (35 chars, 1 line break) UTF-8 P 4 spaces...
|
NULL
|
1865576494599190414
|
NULL
|
click
|
ocr
|
NULL
|
PhostormVIewINavicareCodeLaravelKeractorFV faVsco. PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcache.pnp© SyncPlanhat.php©syncleammeradata.ong1estPlpeariveomricialsakcommand.or© createActivityAdded loPlaylistevent.pnpUpoateopponunityspecrications.onocreatePlaybookcreatedevent.ong>@ Dealinsights• … Dev>C Dialersc) IntearationApp/Service.php(C) LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC) CreateCommentedEvent.phpC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.phoC Elasticsearch(C)AskAnvthinaPromotService.oho(C)AutomatedReportsRepositorv.ohd› Enqagementstatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohoC) RequestGenerateReport.Job.oho/• Livestream(C) AutomatedReportkesulconp(C) AutomatedRenort nhn XMallboxesclass AutomatedRenont extends Modella Midrate46 y1Y6APlavbackithemes141return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:M PlavbooksPlaylists143> M Postmarkpublic function isExpired: boolf...}> M PronhetAv Reports© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.phtpublic function canExecute@: boolf...;public function getActivitvSearchido: ?int-...=(C) CroateMockAck.liminnvRenortResult@© DeleteReportCommand.php© GenerateMarketingReport.phppublic function getAskAnvthingPromptIdO: 2intf...}© Team.php© Usage.phpnublic function aetExoiresAto: 2Carhons...->07 Slack›_ TeamsServicesToC exOutputtid jiminny.social_accounts xv M Databasedid w 1 rowvvAEU#consolee idv&jiminny@localhost# HS localsociable 1dA SFA PRODW provider_user_id! provider_user_token« console(• provider refresh tokenA STAGINGI expires# console 2 s 241 msy, NoshorM refresh token expiresU oroviden!O state1 auth_scopeI retry afterI created atundated at1 row retrieved ctartina from 1 in 740 mc leyecution: 186 mc fetchina: 554 mgDally - Platrorm • now100% S2• Mon 18 May 9:54:02AskJiminnyReportActivityServiceTest v+0 ..=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU<:onodeclare(strict types=1)namespace Jiminny Console commands Crm:use carbon caroon:use Excentlonsuse iLLuminate Console Command:use Jiminny Comoonent EncrvotionEncrvotedtokenManager:use Jiminny Models\SocialAccount;use Jiminny Models Teamuse Jiminny Models \User,use Pipedrive\versions\v1\Api \ActivitiesApi;use Pipedrive\versions\v1\Api\ActivityFieldsApi;use Pipedrive\versions\v1\Api \DealFieldsApi;use Pipedrive\versions\v1\Api\DealsApi;use Pipedrive\versions\v1\Api \PersonFieldsApi;use Pipedrive verszons ve Apt rersonsapluse Pipedrive\versions\v1 \Configuration;22 Dclass lestPipedrive0fficialSdkcommand extends Commandl24 Cprotected ssiqnature = '71m1nny:test-p1pedrive-off1c1al-sak teamlor'n26 đprotected sdescription -AocesFoaCiX Pipednive Sok (papedrive /pipednive) wäth exitDebugging Pipedrive S•Get Person rielas. ogs.oms (/ Tielas)• Get Activity Fields: 1005.95ms (35 fields)Error Handling• Invalid Token Error: 1067.26ms (correctly throws 401)•Non-existent Resource Error: 796.42ms (correctly throws 404)Expected Failure (1/10)VZ APl suppon• V1 API works but v2 cursor pagination not available in official SDK v1• Solution: Use direct Hiitp calls tor v2 endooints or uoarade to Sok v2 when avallablelConclusionThe official Pipedrive SDK is viable for migration. The token format is compatible, core operations work correctly, and error handling functions properly. The main work will bes1. Method name mapping between community and official SDKs2. Response structure adaptation2. v2 APl imnlementation (direct HTTP calls or SDK unarado)Total execution time: 7.6 seconds2) Reject allAccept allwe should use v2 with new SDK. Are vou usina new SDK?+ &codeSWE.1G1116241.19555731|V1U:AQLBAHS -L2 TNK2yuuuaLq142hWb9crUNKTpk4=-109r5nXap_6AE0hDhDQVa1nvWCHEVnpVSEAAAAFB8BqKahk:G9WOBBwagbzBtAgEAMGgGCSqGS1D3D0EHATAeB9LghkgBZ0MEAS4wEQQMnG8KNCZLI5EnLRPXA9EQgDsGP1CKfI5MU/0eL36BtM5FCQa56mYUy24_AAoqdh2y;V=ka6egLqSOinp-5G4JE/frJURMV8VIW-FY149HGHSO8DKUSBq30JM398MH84Cb10mzCrXaVo2GbZEd6nn5034113:[TELEGRAM_TOKEN]b2bfc1779088398oinedriveconnectedibase.deals:full.activities:full.contacts:full,search:read2023-09-08 09:44:292026-05-15 15:44•31W Windsurf Toams137:1 (35 chars, 1 line break) UTF-8 P 4 spaces...
|
49714
|
NULL
|
NULL
|
NULL
|
|
49719
|
NULL
|
0
|
2026-05-18T06:54:16.246412+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087256246_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
3740816030388009784
|
-8636489586330588030
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0.meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 ProM( Ate x | E3 мO x() Sche x |© Curs x* Cia xCost Xom x@vo xPipe xD Cahttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps02 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© SmiC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% 128•Mon 18 May 9:54:16Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPREMMMIE A-CUE 6!Aneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik7:50Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49720
|
1769
|
0
|
2026-05-18T06:54:19.271+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087259271_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
159902063232581519
|
-8204417045388611642
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
IDE and Project Settings
FirefoxEditTools> 0**18FileViewHistoryBookmarksProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 Prom( Ate x | E3 мо x() Sche x|© Curs x* Ca XCost xoum x@vo xPipe xhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps07 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item, Add designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting CenterArchived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)9:54 AM | Daily - Platform© Smi• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% L28• Mon 18 May 9:54:1900Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPRESIIEA QUE GOOSAneliya AngelovaLukas Kovalik7:53I11Lộ3...
|
49719
|
NULL
|
NULL
|
NULL
|
|
49721
|
1769
|
1
|
2026-05-18T06:54:31.373450+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087271373_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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,"role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
-5144026249968099006
|
1739586043254377858
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
FirefoxEditTools> 0.Daily - Platform • now100% 128•Mon 18 May 9:54:31**18FileViewHistoryBookmarksProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0Mon 18 May 9:54yServC7 (SRD83 5miE3 ProM( Ate x | E3 мO x() Sche x |© Curs x* Cia xCost Xom x@vo xPipe x© Smihttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps02 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeimage-20260515-114153.pngCoaching Profiies - Ape 2026 - Strategic Account Managers,patSizeDate added+1.2 MB 15 May 2026, 12:42 pm72 KB15 May 2026, 12:18 pmJiminny (New)9:54 AM | Daily - Platform• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aSteliyan GeorgievNikolay IvanovPREMIAALukas Kovalik8:05006Nikolay YankovAneliya AngelovaI11Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49722
|
1769
|
2
|
2026-05-18T06:54:34.402889+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087274402_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
8681765016529791095
|
-8348540754415211066
|
visual_change
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
AskJiminnyReportActivityServiceTest
Run 'AskJiminnyReportActivityServiceTest'
Debug 'AskJiminnyReportActivityServiceTest'
More Actions
JetBrains AI
Search Everywhere
FirefoxEditTools> 0**18FileViewHistoryBookmarksProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 Prom( Ate x | E3 мо x() Sche x|© Curs x* Ca XCost xoum x@vo xPipe xhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps07 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item, Add designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)9:54 AM | Daily - Platform© Jm• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% L28• Mon 18 May 9:54:34006Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPRFMIIAAneliya AngelovaLukas Kovalik8:08I11Lộ3...
|
49721
|
NULL
|
NULL
|
NULL
|
|
49723
|
1770
|
0
|
2026-05-18T06:54:36.167832+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087276167_m2.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections...
|
[{"role":"AXButton","text" [{"role":"AXButton","text":"Project: faVsco.js, menu","depth":5,"bounds":{"left":0.025930852,"top":0.019952115,"width":0.03856383,"height":0.025538707},"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"pipedrive-sdk-poc, menu","depth":5,"bounds":{"left":0.064494684,"top":0.019952115,"width":0.05618351,"height":0.025538707},"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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}]...
|
4013489942575271730
|
-7483500116281160310
|
idle
|
hybrid
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, menu
Start Listening for PHP Debug Connections
PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcache.pnp© SyncPlanhat.php©syncleammetadata.ong1estPlpeariveomricialsakcommand.or© createActivityAdded loPlaylistevent.pnpUpoateopponunityspecrications.onocreatePlaybookcreatedevent.ong>@ Dealinsights• … Dev>C Dialersc) IntearationApp/Service.php(C) LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC) CreateCommentedEvent.phpC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.phoC Elasticsearch(C)AskAnvthinaPromotService.oho(C)AutomatedReportsRenositorv.ohd› Enqagementstatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohoC) RequestGenerateReport.Job.oho/• Livestream(C) AutomatedReportkesulconp(C) AutomatedRenort nhn XMallboxesclass AutomatedRenont extends Mode]lia Midrate46 Y1Y6 APlavbackithemes141return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:M Plavbooks143D Playlists> M Postmarkpublic function isExpired: boolf...}> M PronhetAv D Reports© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.phtpublic function canExecute@: boolf...;public function getActivitvSearchido: ?int-...=(C) CroateMockAck.liminnvRenortResult@© DeleteReportCommand.php© GenerateMarketingReport.phppublic function getAskAnvthingPromptIdO: 2intf...}© Team.php© Usage.phpnublic function aetExniresAtO: 2Carhons...->07 Slack›_ TeamsServicesToC exOutputtid jiminny.social_accounts xv M Databasedid w 1 rowvvAEU#consolee idv&jiminny@localhost# HS localsociable 1dA SFA PRODW provider_user_id! provider_user_token« console(• provider refresh tokenA STAGINGI expires# console 2 s 241 msy, NoshorM refresh token expiresU oroviden!O state1 auth_scopeI retry afterI created atundated at1 row retrieved ctartina from 1 in 740 mc (eyecution: 186 mc fetchina- 554 mclDaily - Platform - now100% C4• • Mon 18 May 9:54:35AskJiminnyReportActivityServiceTest v+0 ..=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU<:onodeclare(strict types=1)namespace Jiminny Console commands Crm:use carbon caroon:use Excentlonsuse illuminate Console Command:use Jiminny Comoonent Encrvotion EncrvotedtokenManager:use Jiminny Models\SocialAccount;use Jiminny Models. Teamuse Jiminny Models \User,use Pipedrive\versions\v1\Api \ActivitiesApi;use Pipedrive\versions\v1\Api\ActivityFieldsApi;use Pipedrive\versions\v1\Api \DealFieldsApi;use Pipedrive\versions\v1\Api\DealsApi;use Pipedrive\versions\v1\Api\PersonFieldsApi;use Pipedrive verszons ve Apt rersonsaplluco Dinodnivo voncione wn ConSiaunation.22 Dclass lestPipedrive0fficialSdkCommandextends Commandl24 Cprotected ssiqnature = '71m1nny:test-p1pedrive-off1c1al-sak teamlor'n26 đprotected sdescription -AocesFoaCiX Pipednive Sok (papedrive /pipednive) wäth exitDebugging PipedriveThoughts0 3 tasks done• Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallable• Test v2 API endpoints with official SDKSearching v2 in vendor/pipedrive (0)Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiNavigating.we should use v2 with new SDK. Are vou usina new SDK?24les 190-12>Ask anvthina (*4L)+ & codeSWE.1G2) Reject allAccept allO00A :=1116241.19555731|V1U:AQLBAHS -L2 TNK2yuuuaLq142hWb9crUNKTpk4=-109r5nXap_6AE0hDhDQVa1nvWCHEVnpVSEAAAAFB8BqKahk:G9WOBBwagbzBtAgEAMGgGCSqGS1D3D0EHATAeB9LghkgBZ0MEAS4wEQQMnG8KNCZLI5EnLRPXA9EQgDsGP1CKfI5MU/0eL36BtM5FCQa56mYUy24_AAoqdh2y;V=ka6egLqSOinp-5G4JE/frJURMV8VIW-FY149HGHSO8DKUSBq30JM398MH84Cb10mzCrXaVo2GbZEd6nn5034113:[TELEGRAM_TOKEN]b2bfc1779088398<null)oinedriveconnectedlbase.deals:full.activities:full.contacts:full.search:read2023-09-08 09:44:292026-05-15 15:44•31W Windsurf Teams 137:1 (35 chars, 1 line break) UTF-8Po 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49724
|
1769
|
3
|
2026-05-18T06:54:37.399782+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087277399_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0.meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 Prom( Ate x | E3 мо x() Sche x|© Curs x* 0a xCost Xoum x@vo xPipe xD Cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps07 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item, Add designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© SmiC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКOроrtn€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% L28•Mon 18 May 9:54:37006Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPRFMIAAAneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik8:11Lộ3...
|
NULL
|
4075529011981288422
|
NULL
|
visual_change
|
ocr
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0.meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 Prom( Ate x | E3 мо x() Sche x|© Curs x* 0a xCost Xoum x@vo xPipe xD Cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps07 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item, Add designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© SmiC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКOроrtn€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% L28•Mon 18 May 9:54:37006Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPRFMIAAAneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik8:11Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49725
|
1769
|
4
|
2026-05-18T06:54:43.446344+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087283446_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.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,"on_screen":true,"help_text":"~/jiminny/app","role_description":"button","is_enabled":true}]...
|
8043719072324535154
|
-8628527368849355612
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
Firefox**18FileEditViewHi Project: faVsco.js, menu
Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtyServC7 (SRD83 5miE3 ProM( Alte x | E3 мO x() Sche x |© Curs x* Cia xCost xY04Q00 Jmi x | Q MCPPipe xhttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps02 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logs% Developer escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© Smi• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% L8•Mon 18 May 9:54:43006Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPREIMMEA A-CHIE 6IAneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik• 8:17Lộ3...
|
49724
|
NULL
|
NULL
|
NULL
|
|
49726
|
1770
|
1
|
2026-05-18T06:54:43.446401+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087283446_m2.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, 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}]...
|
8043719072324535154
|
-8628527368849355612
|
click
|
hybrid
|
NULL
|
Project: faVsco.js, menu
PhostormVIewINavicareCode Project: faVsco.js, menu
PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.php(c) ConvertLeadActivities.onp ~OPurgeLookupcache.pnp© SyncPlanhat.php©syncleammetadata.ong1estPlpeariveomricialsakcommand.or© createActivityAdded loPlaylistevent.pnpUpoateopponunityspecrications.onocreaterlaybookcreatedevent.phg>@ Dealinsights• … Dev>C Dialersc) IntearationApp/Service.php(C) LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC) CreateCommentedEvent.phpC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.phoC Elasticsearch(C)AskAnvthinaPromotService.oho(C)AutomatedReportsRenositorv.ohd› Enqagementstatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohoC) RequestGenerateReport.Job.oho/• Livestream(C) AutomatedReportkesulconp(C) AutomatedRenort nhn XMallboxesclass AutomatedRenont extends Mode]lia Midrate46 Y1Y6 APlavbackithemes141return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:M PlavbooksPlaylists143> M Postmarkpublic function isExpired: boolf...}> M PronhetAv D Reports© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.phtpublic function canExecute@: boolf...;public function getActivitvSearchido: ?int-...=(C) CroateMockAck.liminnvRenortResult@© DeleteReportCommand.php© GenerateMarketingReport.phppublic function getAskAnvthingPromptIdO: 2intf...}© Team.php© Usage.phpnublic function aetExoiresAtO: 2Carhons...>07 Slack›_ TeamsServicesToC exOutputGid jiminny.social_accounts xv M Databasedid w 1 rowvvAEU#consolee idv&jiminny@localhost# HS localI sociable 1dA SFA PRODW provider_user_id! provider_user_token« console(• provider refresh tokenA STAGINGI expires# console 2 s 241 msy, NoshorM refresh token expiresU oroviden!O state1 auth_scopeI retry afterI created atundated at1 row retrieved ctartina from 1 in 740 mc (eyecution: 186 mc fetchina- 554 mcl=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU<:onodeclare(strict types=1)namespace Jiminny Console commands crm:use carbon caroon:use Excentlonsuse illuminate Console Command:use Jiminny Comoonent Encrvotion EncrvotedtokenManager:use Jiminny Models\SocialAccount;use Jiminny Models. Teamuse Jiminny Models \User,use Pipedrive\versions\v1\Api \ActivitiesApi;use Pipedrive\versions\v1\Api\ActivityFieldsApi;use Pipedrive\versions\v1\Api \DealFieldsApi;use Pipedrive\versions\v1\Api\DealsApi;use Pipedrive\versions\v1\Api\PersonFieldsApi;use Pipedrive verszons ve apt rersonsapluse Pipedrive\versions\v1 \Configuration;22 Dclass lestPipedrive0fficialSdkCommandextends Commandl24 đprotected ssiqnature = '71m1nny:test-p1pedrive-off1c1al-sak teamlor'n26 đAccept File &+nrotected Slesent tion AcetfieoiX Pinede ve SoK ( 1oedhive Dipednive) wäth extDaily - Platform • now100% C4• • Mon 18 May 9:54:42AskJiminnyReportActivityServiceTest v+0 ..we should use v2 with new SDK. Are vou usina new SDK?• Debugging PipedriveThoughts0 3 tasks done• Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallable• Test v2 API endpoints with official SDKSearching v2 in vendor/pipedrive (0)Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiC TestPipedriveOfficialSdkCommand.php24les 190-12>Ask anvthina (*4L)+ & codeSWE.1G2) Reject allAccept all1116241.19555731|V1U:AQLBAHS -L2 TNK2yuuuaLq142hWb9crUNKTpk4=-109r5nXap_6AE0hDhDQVa1nvWCHEVnpVSEAAAAFB8BqKahk:G9WOBBwagbzBtAgEAMGgGCSqGS1D3D0EHATAeB9LghkgBZ0MEAS4wEQQMnG8KNCZLI5EnLRPXA9EQgDsGP1CKfI5MU/0eL36BtM5FCQa56mYUy24_AAoqdh2y;V=ka6egLqSOinp-5G4JE/frJURMV8VIW-FY149HGHSO8DKUSBq30JM398MH84Cb10mzCrXaVo2GbZEd6nn5034113:[TELEGRAM_TOKEN]b2bfc1779088398oinedriveconnectedibase.deals:full.activities:full.contacts:full.search:read2023-09-08 09:44:292026-05-15 15:44•31W Windsurf Toams 127-1/25 charc 1 line hreak)UTF.8Po 4 spaces...
|
49723
|
NULL
|
NULL
|
NULL
|
|
49728
|
1770
|
2
|
2026-05-18T06:54:47.686730+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087287686_m2.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhpStormVIewINavicareCodeLaravelKeractorFV faVsco. PhpStormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect v©ActivityController.php© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcacne.ong© SyncPlanhat.php©syncleammeradata.ong1estPlpeariveomricialsakcommand.orUpoateopponunityspecrications.onocreaterlaybookcreatedevent.phg©) salestorce/service.php>@ Dealinsights>@Dev> 0 Dialersc) IntearationApp/Service.php© LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.phoC Elasticsearch(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv> Livestream(C) AutomatedReportkesult.onp(C) AutomatedReport.phpMallboxesa Midratefinal class ActivityController extends Controller implements CommentContextIntPlavbacktihemespublic function listActivitySearch(Request $request, SearchTransformer SsearoM PlavbooksM Plavlists111> M Postmark* Veletes a saved search> M PronhetAv M Renorto© AutomatedReportsCommand.php* doaram search ssearch=(C) AutomatedReportsRetentionPolicycor 1111C AutomatedReportsSendCommano.on 1112* athrows Exception© CreateMockAskJiminnyReportResultC 1113- 21c) DeleteRenortcommana.ong* dreturn JsonResponse© GenerateMarketingReport.php© Team.php© Usage.phppublic function deleteActivitySearch(Request $request, Search $search): Jsonk24 đ>CJ Slacknublic function uiveRequest Sreguest. ElasticActivitvRenositorv Srenositorv)›_ Teams26 6Local ChangesShelConsole XLog xTL0<→?= env.local apocomooser.ison apolcomooser.lock aodKernel.oho aoo/Console#loadina,oho contialUnversioned Files 10 files=custom.log=laravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU<:onodeclare(strict types=1)use carbon caroon:use Excentlonsuse illuminate Console Command:use Jiminny Comoonent Encrvotion EncrvotedtokenManager:use Jiminny Models SocialAccount.use Jiminny Models Teamuse Jiminny Models \User,luse Pinedrive vensions vilAnt Activitiecani:use Pipedrive\versions\v1\Api\ActivityFieldsApi;luse Pinedrive vencions v1 Ani NealFieldsAni:use Pipedrive\versions\v1\Api\DealsApi;luse Pinednive vencions v1 Ani PenconSieldsAni•use Pipedrive verszons ve Apt rersonsaplluco Dinodnivo voncione wn ConSiaunation.class TestPipedrive0fficialSdkCommand extends Commandprotected Ssignature = 'jiminny:test-pipedrive-official-sdk {teamId}':protected Sdescription = 'Test official Pipedrive SDK (pipedrive/pipedrive) with exisNothina to show"Dally - Platrorm • now100% Sz• Mon 18 May 9:54:47AskJiminnyReportActivityServiceTest vDebugging PipedriveThoughts0 3 tasks done• Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallable• Test v2 API endpoints with official SDKSearching v2 in vendor/pipedrive (0)Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts>Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiDivingTestPipedriveOfficialSdkCommand.phpwe should use v2 with new SDK. Are you using new SDK?10/ tokens2) Reject allAccept allAsk anvthina (*4L)+ & codeSWE-1.6W Windsurf Teams 1090:39 UTF-8 P 4 spaces...
|
NULL
|
-4471556435091548072
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhpStormVIewINavicareCodeLaravelKeractorFV faVsco. PhpStormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect v©ActivityController.php© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcacne.ong© SyncPlanhat.php©syncleammeradata.ong1estPlpeariveomricialsakcommand.orUpoateopponunityspecrications.onocreaterlaybookcreatedevent.phg©) salestorce/service.php>@ Dealinsights>@Dev> 0 Dialersc) IntearationApp/Service.php© LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.phoC Elasticsearch(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohdC) RequestGenerateReport.Job.ohv> Livestream(C) AutomatedReportkesult.onp(C) AutomatedReport.phpMallboxesa Midratefinal class ActivityController extends Controller implements CommentContextIntPlavbacktihemespublic function listActivitySearch(Request $request, SearchTransformer SsearoM PlavbooksM Plavlists111> M Postmark* Veletes a saved search> M PronhetAv M Renorto© AutomatedReportsCommand.php* doaram search ssearch=(C) AutomatedReportsRetentionPolicycor 1111C AutomatedReportsSendCommano.on 1112* athrows Exception© CreateMockAskJiminnyReportResultC 1113- 21c) DeleteRenortcommana.ong* dreturn JsonResponse© GenerateMarketingReport.php© Team.php© Usage.phppublic function deleteActivitySearch(Request $request, Search $search): Jsonk24 đ>CJ Slacknublic function uiveRequest Sreguest. ElasticActivitvRenositorv Srenositorv)›_ Teams26 6Local ChangesShelConsole XLog xTL0<→?= env.local apocomooser.ison apolcomooser.lock aodKernel.oho aoo/Console#loadina,oho contialUnversioned Files 10 files=custom.log=laravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EU<:onodeclare(strict types=1)use carbon caroon:use Excentlonsuse illuminate Console Command:use Jiminny Comoonent Encrvotion EncrvotedtokenManager:use Jiminny Models SocialAccount.use Jiminny Models Teamuse Jiminny Models \User,luse Pinedrive vensions vilAnt Activitiecani:use Pipedrive\versions\v1\Api\ActivityFieldsApi;luse Pinedrive vencions v1 Ani NealFieldsAni:use Pipedrive\versions\v1\Api\DealsApi;luse Pinednive vencions v1 Ani PenconSieldsAni•use Pipedrive verszons ve Apt rersonsaplluco Dinodnivo voncione wn ConSiaunation.class TestPipedrive0fficialSdkCommand extends Commandprotected Ssignature = 'jiminny:test-pipedrive-official-sdk {teamId}':protected Sdescription = 'Test official Pipedrive SDK (pipedrive/pipedrive) with exisNothina to show"Dally - Platrorm • now100% Sz• Mon 18 May 9:54:47AskJiminnyReportActivityServiceTest vDebugging PipedriveThoughts0 3 tasks done• Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallable• Test v2 API endpoints with official SDKSearching v2 in vendor/pipedrive (0)Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts>Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiDivingTestPipedriveOfficialSdkCommand.phpwe should use v2 with new SDK. Are you using new SDK?10/ tokens2) Reject allAccept allAsk anvthina (*4L)+ & codeSWE-1.6W Windsurf Teams 1090:39 UTF-8 P 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49727
|
1769
|
5
|
2026-05-18T06:54:48.657309+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087288657_m1.jpg...
|
PhpStorm
|
faVsco.js – ActivityController.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtyServC7 (SRD83 5miE3 ProM( Alte x | E3 мO x() Sche x |© Curs x* Cia xCost xY04Q00 Jmi x | Q MCPPipe xhttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps02 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logs% Developer escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© Smi• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% C8• Mon 18 May 9:54:48Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPREMMIIL A-CIlE 60Aneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik8:22Lộ3...
|
NULL
|
-913059505698637232
|
NULL
|
click
|
ocr
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtyServC7 (SRD83 5miE3 ProM( Alte x | E3 мO x() Sche x |© Curs x* Cia xCost xY04Q00 Jmi x | Q MCPPipe xhttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps02 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logs% Developer escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© Smi• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% C8• Mon 18 May 9:54:48Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPREMMIIL A-CIlE 60Aneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik8:22Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49729
|
1770
|
3
|
2026-05-18T06:54:53.208874+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087293208_m2.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormVIewINavicareCodeLaravelKeractorFV faVsco. PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect©ActivityController.php© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcacne.ong© SyncPlanhat.php©syncleammeradata.ong© TestPipedriveOfficialSdkCommand.phUpaateupporunityspectications.onoc createrlaybookcreatedevent.ong©) salestorce/service.php>@ Dealinsights>@Dev> 0 Dialersc) IntearationApp/Service.php© LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC) CreateCommentedEvent.phpC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.phoC Elasticsearch(C)AskAnvthinaPromotService.oho(C)AutomatedReportsRepositorv.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohoC) RequestGenerateReport.Job.ohv>D Livestream(C) AutomatedReportkesult.onp(C) AutomatedReport.phpMallboxes• Mioratefinal class ActivityController extends Controller implements CommentContextIntPlavbackithemespublic function listActivitySearch(Request $request, SearchTransformer Sseam:M PlavbooksM Plavlists/** @var User Suser *> M PostmarkSuser = $request->userO:> M PronhetAv M RenortoSthis->response© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 1097->getManagerO-›serserauzertnew Jsonserzalzzer(00:© AutomatedReportsSendCommand.pht 1098© CreateMockAskJiminnyReportResultC 1099nse->withCollection(© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php->withconsumer(Suser)>CJ Slack›_ TeamsLocal ChanaesLog X=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]=III20=22D24 otHIII IIII26 6tA console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipearive versions vI Ap1 Fersonrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:use Pipedrive versions v2 Ani ActivitiecAni.use rrpearive verszons ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealsAp1:use Pipedrive versions\v2\Api\PersonFieldsApi:use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends CommandAccept Rejectprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.private arnay edfgsylt Accept File g-X Reject File 0x@+ 20f2 files →TIO+→?Nothina to show1 row retrieved ctartina from 1 in 740 mc leyecutioDebugging PipedriveTnoughts03 tasks done•Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallableTest v2 APl endpoints with official SDKSearched v2 in vendor/pipedrive (2)Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts>Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiTestPipedriveOfficialSdkCommand.phpSurfindAsk anvthina (*4L)+ &CodeSWE-1.6"Dally - Platrorm • now100% Lz• Mon 18 May 9:54:52AskJiminnyReportActivityServiceTest vwe should use v2 with new SDK. Are you using new SDK?J 205 tokensl2) Reject allAccept all090W Windsurf Teams 14:1 (35 chars, 1 line break) UTF-8 ia 4 spaces...
|
NULL
|
-1064894816101463328
|
NULL
|
visual_change
|
ocr
|
NULL
|
PhostormVIewINavicareCodeLaravelKeractorFV faVsco. PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect©ActivityController.php© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcacne.ong© SyncPlanhat.php©syncleammeradata.ong© TestPipedriveOfficialSdkCommand.phUpaateupporunityspectications.onoc createrlaybookcreatedevent.ong©) salestorce/service.php>@ Dealinsights>@Dev> 0 Dialersc) IntearationApp/Service.php© LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC) CreateCommentedEvent.phpC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.phoC Elasticsearch(C)AskAnvthinaPromotService.oho(C)AutomatedReportsRepositorv.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohoC) RequestGenerateReport.Job.ohv>D Livestream(C) AutomatedReportkesult.onp(C) AutomatedReport.phpMallboxes• Mioratefinal class ActivityController extends Controller implements CommentContextIntPlavbackithemespublic function listActivitySearch(Request $request, SearchTransformer Sseam:M PlavbooksM Plavlists/** @var User Suser *> M PostmarkSuser = $request->userO:> M PronhetAv M RenortoSthis->response© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 1097->getManagerO-›serserauzertnew Jsonserzalzzer(00:© AutomatedReportsSendCommand.pht 1098© CreateMockAskJiminnyReportResultC 1099nse->withCollection(© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php->withconsumer(Suser)>CJ Slack›_ TeamsLocal ChanaesLog X=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]=III20=22D24 otHIII IIII26 6tA console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipearive versions vI Ap1 Fersonrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:use Pipedrive versions v2 Ani ActivitiecAni.use rrpearive verszons ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealsAp1:use Pipedrive versions\v2\Api\PersonFieldsApi:use Pipedrive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends CommandAccept Rejectprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.private arnay edfgsylt Accept File g-X Reject File 0x@+ 20f2 files →TIO+→?Nothina to show1 row retrieved ctartina from 1 in 740 mc leyecutioDebugging PipedriveTnoughts03 tasks done•Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallableTest v2 APl endpoints with official SDKSearched v2 in vendor/pipedrive (2)Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts>Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiTestPipedriveOfficialSdkCommand.phpSurfindAsk anvthina (*4L)+ &CodeSWE-1.6"Dally - Platrorm • now100% Lz• Mon 18 May 9:54:52AskJiminnyReportActivityServiceTest vwe should use v2 with new SDK. Are you using new SDK?J 205 tokensl2) Reject allAccept all090W Windsurf Teams 14:1 (35 chars, 1 line break) UTF-8 ia 4 spaces...
|
49728
|
NULL
|
NULL
|
NULL
|
|
49730
|
1769
|
6
|
2026-05-18T06:54:54.212493+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087294212_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0.meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 ProM( Ate x | E3 мO x() Sche x |© Curs x* Cia xCost Xom x@vo xPipe xhttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps02 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© Smi• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% 2.8• Mon 18 May 9:54:5300Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPRFMMIRA AECIlE 6IAneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik8:28Lộ3...
|
NULL
|
7015435210606598805
|
NULL
|
visual_change
|
ocr
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0.meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 ProM( Ate x | E3 мO x() Sche x |© Curs x* Cia xCost Xom x@vo xPipe xhttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps02 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© Smi• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% 2.8• Mon 18 May 9:54:5300Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovPRFMMIRA AECIlE 6IAneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik8:28Lộ3...
|
49727
|
NULL
|
NULL
|
NULL
|
|
49731
|
1769
|
7
|
2026-05-18T06:54:57.526012+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087297526_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 Prom( Ate x | E3 мо x() Sche x|© Curs x* Ca XCost xoum x@vo xPipe xhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps07 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item, Add designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© Jm• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% C8• Mon 18 May 9:54:57=00Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovAneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik8:31Lộ3...
|
NULL
|
-7087812534686553608
|
NULL
|
visual_change
|
ocr
|
NULL
|
Firefox**18FileEditViewHistoryBookmarksProfilesToo Firefox**18FileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtY04Q0yServC7 (SRD83 5miE3 Prom( Ate x | E3 мо x() Sche x|© Curs x* Ca XCost xoum x@vo xPipe xhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps07 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item, Add designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logsDeveloper escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)© Jm• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aDaily - Platform • now100% C8• Mon 18 May 9:54:57=00Mon 18 May 9:54Steliyan GeorgievNikolay YankovNikolay IvanovAneliya Angelova9:54 AM | Daily - PlatformLukas Kovalik8:31Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49732
|
1769
|
8
|
2026-05-18T06:55:09.862653+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087309862_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxEditTools> 0**- 18FileViewHistoryBookmar FirefoxEditTools> 0**- 18FileViewHistoryBookmarksProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtyServC7 (SRD83 5miE3 ProM( Alte x | E3 мO x() Sche x |© Curs x* Ca XCost XY04Q00 Jmi x | Q MCPPipe xhttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps02 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logs% Developer escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)9:55 AM | Daily - PlatformLộ3© Jm• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aà Daily - Platform - 10 m left100% C8• Mon 18 May 9:55:09006Mon 18 May 9:56Steliyan GeorgievNikolay YankovNikolay IvanovAneliya AngelovaLukas Kovalik8:44...
|
NULL
|
-867248625793717094
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxEditTools> 0**- 18FileViewHistoryBookmar FirefoxEditTools> 0**- 18FileViewHistoryBookmarksProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleTdtyServC7 (SRD83 5miE3 ProM( Alte x | E3 мO x() Sche x |© Curs x* Ca XCost XY04Q00 Jmi x | Q MCPPipe xhttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859Projects• Home | Salesforce* Claudeecrоre!Sentry*xIL tasк+ Create® For you© Recent|# Starred8? Apps02 Spacesauurco5 Service-Desk|@ Summary@ Queues< Back30 3К0-66501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreatevGabriela Dureva raised this request via JiraDescriptionHi team,plenleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• Channeisl8 Emall logs% Developer escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this comversation so the call shouldnt be the scope of her summary. E Coaching Profities - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmJiminny (New)9:55 AM | Daily - PlatformLộ3© Jm• caC DevAsk RovoAhaiyzingDetailsAssignee32 Stelyan GeorgievAssign to meКОРОRTR€ Gabrieta DurevaRequest TypeNoneKnowledge base View reiated…Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aà Daily - Platform - 10 m left100% C8• Mon 18 May 9:55:09006Mon 18 May 9:56Steliyan GeorgievNikolay YankovNikolay IvanovAneliya AngelovaLukas Kovalik8:44...
|
49731
|
NULL
|
NULL
|
NULL
|
|
49733
|
1769
|
9
|
2026-05-18T06:55:12.888760+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087312888_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, 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…
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $this->request->user();
$favorit...
|
[{"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":"pipedrive-sdk-poc, menu","depth":5,"on_screen":true,"help_text":"Git Branch: pipedrive-sdk-poc","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":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","depth":4,"on_screen":true,"value":"<?php\n\nnamespace Jiminny\\Http\\Controllers\\API;\n\nuse Carbon\\Carbon;\nuse ChaseConey\\LaravelDatadogHelper\\Datadog;\nuse Exception;\nuse Illuminate\\Auth\\Access\\AuthorizationException;\nuse Illuminate\\Database\\Eloquent\\Builder;\nuse Illuminate\\Http\\JsonResponse;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Collection;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Validation\\Rule;\nuse Illuminate\\Validation\\Rules\\In;\nuse Illuminate\\Validation\\ValidationException;\nuse InvalidArgumentException;\nuse Jiminny\\Component\\ActivityAnalytics;\nuse Jiminny\\Component\\ActivitySearch;\nuse Jiminny\\Component\\ActivitySearch\\FilterDefinitionCollection;\nuse Jiminny\\Component\\PlaybackPage\\Comments\\Services\\ActivityCommentService;\nuse Jiminny\\Component\\Queue\\Constants;\nuse Jiminny\\Contracts\\ES\\Events\\UpdateSingleEntity;\nuse Jiminny\\Contracts\\ES\\UpdateTargetEnum;\nuse Jiminny\\Contracts\\Nudge\\NudgeFactoryInterface;\nuse Jiminny\\Contracts\\Playlist\\PlaylistTrackFactoryInterface;\nuse Jiminny\\Contracts\\Repositories\\PlaylistActivityRepository;\nuse Jiminny\\Contracts\\Services\\Crm\\ServiceInterface;\nuse Jiminny\\Enums\\TeamSetting;\nuse Jiminny\\Events\\Activities\\AiAutomation\\ActivityProspectAdded;\nuse Jiminny\\Events\\Activities\\Coaching\\Coached;\nuse Jiminny\\Contracts\\Services\\Crm\\SupportsObjectTypeParseInterface;\nuse Jiminny\\Exceptions\\LogicException;\nuse Jiminny\\Exceptions\\SocialAccountTokenInvalidException;\nuse Jiminny\\Http\\Controllers\\API\\BaseController as Controller;\nuse Jiminny\\Http\\Controllers\\CommentContextInterface;\nuse Jiminny\\Http\\Responses\\Api\\AbstractResponse;\nuse Jiminny\\Http\\Responses\\Api\\Response;\nuse Jiminny\\Http\\Serializers\\JsonSerializer;\nuse Jiminny\\Http\\Transformers\\ActivityCommentTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTopicTriggerTransformer;\nuse Jiminny\\Http\\Transformers\\ActivityTransformer;\nuse Jiminny\\Http\\Transformers\\AvailabilityNotificationTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingFeedbackTransformer;\nuse Jiminny\\Http\\Transformers\\CoachingSectionsTransformer;\nuse Jiminny\\Http\\Transformers\\SearchTransformer;\nuse Jiminny\\Http\\Transformers\\StatsTransformer;\nuse Jiminny\\Jobs\\Crm\\SaveActivity;\nuse Jiminny\\Jobs\\Crm\\UpdateStage;\nuse Jiminny\\Jobs\\Telephony\\StartRecording;\nuse Jiminny\\Jobs\\Telephony\\StopRecording;\nuse Jiminny\\Jobs\\Telephony\\ToggleRecording;\nuse Jiminny\\Models\\Account;\nuse Jiminny\\Models\\Activity;\nuse Jiminny\\Models\\Activity\\CoachRequest;\nuse Jiminny\\Models\\Activity\\Comment;\nuse Jiminny\\Models\\Activity\\Search;\nuse Jiminny\\Models\\Activity\\SearchFilter;\nuse Jiminny\\Models\\Activity\\Share;\nuse Jiminny\\Models\\CoachingFeedback;\nuse Jiminny\\Models\\CoachingSection;\nuse Jiminny\\Models\\CoachingSectionCriterion;\nuse Jiminny\\Models\\CoachingSectionFeedback;\nuse Jiminny\\Models\\Contact;\nuse Jiminny\\Models\\Crm\\Field;\nuse Jiminny\\Models\\Crm\\FieldData;\nuse Jiminny\\Models\\Crm\\Layout;\nuse Jiminny\\Models\\Crm\\LayoutEntity;\nuse Jiminny\\Models\\Feature\\FeatureEnum;\nuse Jiminny\\Models\\LanguageDialect;\nuse Jiminny\\Models\\Lead;\nuse Jiminny\\Models\\Nudge;\nuse Jiminny\\Models\\PlaybookCategory;\nuse Jiminny\\Models\\Playlist;\nuse Jiminny\\Models\\Stage;\nuse Jiminny\\Models\\Team;\nuse Jiminny\\Models\\Track;\nuse Jiminny\\Models\\User;\nuse Jiminny\\Repositories\\CoachingFeedbackRepository;\nuse Jiminny\\Repositories\\ElasticActivityRepository;\nuse Jiminny\\Repositories\\TeamRepository;\nuse Jiminny\\Rules\\CrmReference;\nuse Jiminny\\Rules\\MultidimensionalArrayMaxCharRule;\nuse Jiminny\\Services\\ActivityService;\nuse Jiminny\\Services\\Crm\\ProviderRegistry;\nuse Jiminny\\Services\\PlaybackService;\nuse Jiminny\\Services\\UserService;\nuse Jiminny\\VO\\Repository\\OnDemandActivitySearch\\Criteria;\nuse Psr\\Log\\LoggerInterface;\nuse Ramsey\\Uuid\\Uuid;\nuse Sentry;\nuse Symfony\\Component\\HttpFoundation;\n\nfinal class ActivityController extends Controller implements CommentContextInterface\n{\n // Number of minutes to look back on activities. i.e. a timeout on activity duration.\n private const int LOOK_BACK = 180;\n\n public function __construct(\n private ProviderRegistry $providerRegistry,\n private ActivityService $activityService,\n Response $response,\n private UserService $userService,\n private ActivitySearch\\Service\\ActivitySearch $activitySearch,\n private NudgeFactoryInterface $nudgeFactory,\n private ActivityCommentService $activityCommentService,\n private LoggerInterface $logger,\n private readonly CoachingFeedbackRepository $coachingFeedbackRepository,\n private readonly TeamRepository $teamRepository,\n ) {\n parent::__construct($response);\n }\n\n public static function getCommentImplementation(): string\n {\n return Comment::class;\n }\n\n public function delete()\n {\n $this->request->validate([\n '*' => 'uuid:activities',\n ]);\n\n $deletedIds = [];\n foreach ($this->request->all() as $activityId) {\n $activity = Activity::idOrUuId($activityId);\n\n try {\n if ($this->authorize('delete', $activity)) {\n $activity->delete();\n $deletedIds[] = $activityId;\n\n \\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n }\n } catch (AuthorizationException $authorizationException) {\n // They didn't have permission.\n }\n }\n\n return $this->response->withArray($deletedIds);\n }\n\n public function update(Request $request, Activity $activity)\n {\n $this->authorize('updateMetadata', $activity);\n\n $request->validate([\n 'title' => 'string|max:250',\n 'category_id' => 'uuid:playbook_categories',\n 'language' => [\n new In(\n LanguageDialect::query()\n ->with('language')\n ->cursor()\n ->map(static function (LanguageDialect $languageDialect): string {\n return $languageDialect->getLanguageLocale();\n })\n ->all()\n ),\n ],\n ]);\n\n if ($request->has('title')) {\n $activity->title = $request->input('title');\n }\n\n if ($request->has('category_id')) {\n $category = PlaybookCategory::uuid($request->input('category_id'));\n\n if ($category->playbook->team_id !== $request->user()->team_id) {\n return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n if ($request->has('language')) {\n if (! $activity->isInProgress()) {\n return $this->response->withError(\n 'Activity language can only be set while the meeting is in progress.',\n 400\n );\n }\n\n $activity->setLanguageCode($request->input('language'));\n }\n\n $activity->save();\n\n return $this->response->withOk();\n }\n\n // XXX: This should be merged with the update method.\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws SocialAccountTokenInvalidException\n *\n * @return mixed\n */\n public function summarize(Activity $activity): mixed\n {\n $this->logger->info('[Log Activity] Summarizing activity ', [\n 'activityId' => $activity->getUuid(),\n 'payload' => $this->request->all(),\n ]);\n $this->authorize('update', $activity);\n\n $this->logger->info('[Log Activity] Validating summary');\n // Validate the payload.\n $this->validateSummary($activity);\n\n // All objects must belong to this team.\n /** @var User $user */\n $user = $this->request->user();\n $team = $user->getTeam();\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n try {\n $crmUser = $user;\n if ($user->isCrmRequired() === false) {\n $crmUser = $team->owner;\n }\n $crmService->setUser($crmUser);\n } catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());\n }\n\n $rawEntities = $this->request->input('entities');\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid(\n $this->request->input('layout_id')\n );\n\n // Delay execution of CRM jobs to avoid locking issues.\n $jobDelay = 0;\n\n // If we have arrived from a notification, mark it as read.\n $notificationId = $this->request->input('nId');\n if ($notificationId) {\n $notification = $user->unreadNotifications->where('id', $notificationId)->first();\n\n if ($notification) {\n $notification->markAsRead();\n }\n }\n\n $title = $this->request->input('title');\n $prospects = $this->request->input('prospects');\n $opportunityId = $this->request->input('opportunity_id');\n $stageId = $this->request->input('stage_id');\n $categoryId = $this->request->input('category_id');\n $summary = $this->request->input('summary');\n $crmProviderId = $this->request->input('crm_id');\n $isInternal = $this->request->input('is_internal') ?? false;\n\n $lead = null;\n $category = null;\n $account = null;\n $contact = null;\n $opportunity = null;\n $stage = null;\n $callStage = null;\n\n foreach ($prospects as $prospectData) {\n $objectId = $prospectData['id'];\n\n if ($objectId === null) {\n continue;\n }\n\n $objectType = $prospectData['type'];\n $this->logger->info('debug', ['prospect_data' => $prospectData]);\n\n try {\n if ($objectType === null) {\n $this->logger->info('no object type');\n if ($crmService instanceof SupportsObjectTypeParseInterface) {\n $objectType = $crmService->parseObjectType($objectId);\n }\n }\n\n switch ($objectType) {\n case 'lead':\n $this->logger->info('Processing lead');\n /** @var Lead|null $lead */\n $lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();\n\n // Lead does not exist locally, import it.\n if ($lead === null) {\n $this->logger->info('Lead does not exist locally');\n /** @var Lead $lead */\n $lead = $crmService->syncLead($objectId);\n }\n\n $this->logger->info('Lead found', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n if ($stageId === null) {\n $this->logger->info('Stage ID is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $lead->stage;\n\n break;\n }\n\n $this->logger->info('Looking for stage');\n // Determine if they have changed the stage.\n /** @var Stage $stage */\n $stage = $team->crm->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_LEAD)\n ->firstOrFail();\n\n $this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);\n if ($lead->stage_id && $lead->stage_id !== $stage->id) {\n $this->logger->info('Stage has changed');\n // Storage current stage on activity.\n $callStage = $lead->stage;\n\n // The stage has changed, update in remote CRM.\n dispatch(new UpdateStage($activity, $lead, $callStage, $stage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing lead stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->getName(),\n $stage->getName()\n ),\n [\n 'user' => $user->getUuid(),\n 'lead' => $lead->getUuid(),\n ]\n );\n } else {\n $this->logger->info('Stage has not changed');\n // Stage remains as current.\n $callStage = $stage;\n }\n\n break;\n\n case 'account':\n $this->logger->info('Processing account');\n // If the object is not a lead, it should be an account.\n $account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();\n\n // Account does not exist locally, import it.\n if ($account === null) {\n $this->logger->info('Account does not exist locally');\n $account = $crmService->syncAccount($objectId);\n }\n\n $this->logger->info('Account found', ['accountId' => $account->id]);\n\n break;\n case 'contact':\n $this->logger->info('processing contact');\n $contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();\n\n // Contact does not exist locally, import it.\n if (! $contact instanceof Contact) {\n $this->logger->info('contact does not exist locally');\n $contact = $crmService->syncContact($objectId);\n }\n\n $this->logger->info('resolving account');\n $account = $this->resolveAccount($team, $contact, $crmService, $prospects);\n\n break;\n }\n\n // If they have specified an opportunity, retrieve this with stage.\n if ($opportunityId) {\n $this->logger->info('opportunity id is set');\n $opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();\n\n // Opportunity does not exist locally, import it.\n if ($opportunity === null) {\n $this->logger->info('opportunity does not exist locally');\n $opportunity = $crmService->syncOpportunity($opportunityId);\n }\n\n if ($stageId === null) {\n $this->logger->info('stage id is null');\n // If it was not provided, just assume it is the current stage.\n $callStage = $opportunity->stage ?? null;\n } else {\n $this->logger->info('looking for stage');\n /** @var ?Stage $opportunityStage */\n $opportunityStage = $team->crm\n ->stages()\n ->uuid($stageId, false)\n ->where('type', Stage::TYPE_OPPORTUNITY)\n ->first();\n\n // There is a chance we still cannot import this opportunity.\n if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {\n $this->logger->info('opportunity stage has changed');\n // Storage current stage on activity.\n $callStage = $opportunity->stage;\n\n dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));\n\n $this->logger->info(\n sprintf(\n '[%s] User changing opportunity stage from %s to %s',\n $crmService->getDisplayName(),\n $callStage->name,\n $opportunityStage->name\n ),\n [\n 'userId' => $user->id_string,\n 'opportunityId' => $opportunity->id_string,\n ]\n );\n } else {\n $this->logger->info('opportunity stage has not changed');\n // Stage remains as current.\n $callStage = $opportunityStage;\n }\n }\n }\n\n if ($crmProviderId) {\n // Cast $crmProviderId to string otherwise it won't use database index for some records\n $linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();\n\n // Check if this activity has already been assigned to a different activity.\n if ($linkedActivity && $linkedActivity->id !== $activity->id) {\n throw new InvalidArgumentException(\n 'Sorry, the linked task has already been logged under a different call. '\n . 'Please choose another linked task.'\n );\n }\n }\n } catch (InvalidArgumentException $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorWrongArgs($exception->getMessage());\n } catch (Exception $exception) {\n $this->logger->error('Failed to process prospect', [\n 'prospect_data' => $prospectData,\n 'reason' => $exception->getMessage(),\n ]);\n\n // Return a JSON response with the response array and status code.\n return $this->response->errorInternalError(\n 'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'\n );\n }\n }\n\n if ($categoryId) {\n $category = PlaybookCategory::uuid($categoryId);\n\n if ($category->playbook->team_id !== $team->id) {\n throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');\n }\n\n $activity->playbook_category_id = $category->id;\n }\n\n $this->logger->info('Prospect data', [\n 'lead_id' => $lead?->getId(),\n 'account_id' => $account?->getId(),\n 'contact_id' => $contact?->getId(),\n 'opportunity_id' => $opportunity?->getId(),\n 'stage_id' => $stage?->getId(),\n ]);\n\n if ($title) {\n $activity->title = $title;\n }\n\n if ($summary) {\n $activity->summary = $summary;\n }\n\n if ($crmProviderId) {\n $activity->crm_provider_id = $crmProviderId;\n }\n\n if ($callStage) {\n $this->logger->info('Setting stage id', ['stageId' => $callStage->id]);\n $activity->stage_id = $callStage->id;\n }\n\n if ($lead) {\n $this->logger->info('Setting lead id', ['leadId' => $lead->id]);\n $activity->lead_id = $lead->id;\n\n // If we are changed from an account > lead, unset the account data.\n $this->logger->info('Unsetting account id, opportunity id, contact id, value');\n $activity->account_id = null;\n $activity->opportunity_id = null;\n $activity->contact_id = null;\n $activity->value = null;\n }\n\n if ($account) {\n $this->logger->info('Setting account id', ['accountId' => $account->id]);\n $activity->account_id = $account->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('unsetting lead id');\n $activity->lead_id = null;\n\n // Unset the contact if switching different accounts. Will be set up below if still applicable.\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {\n $this->logger->info('Unsetting contact id');\n $activity->contact_id = null;\n }\n }\n\n if ($opportunity) {\n $this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);\n $this->logger->info('unsetting lead id');\n $activity->opportunity_id = $opportunity->id;\n $activity->value = $opportunity->value;\n\n // If we are changed from an lead > account, unset the lead data.\n $activity->lead_id = null;\n }\n\n if ($contact) {\n $this->logger->info('setting contact id', ['contactId' => $contact->id]);\n $activity->contact_id = $contact->id;\n\n // If we are changed from an lead > account, unset the lead data.\n $this->logger->info('Unsetting lead id');\n $activity->lead_id = null;\n }\n\n $activity->is_internal = $isInternal;\n $activity->save();\n $activity->refresh();\n\n $this->logger->notice('Activity saved', [\n 'activity_id' => $activity->getId(),\n 'lead_id' => $activity->lead_id,\n 'account_id' => $activity->account_id,\n 'contact_id' => $activity->contact_id,\n 'opportunity_id' => $activity->opportunity_id,\n 'stage_id' => $activity->stage_id,\n 'crm_provider_id' => $activity->getCrmProviderId(),\n ]);\n\n // Store entities as field data on the activity.\n $updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);\n\n if ($activity->isLoggable()) {\n // Follow-up Task or Event data.\n $followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);\n\n $this->logger->info('CRM LOG manual log triggered', [\n 'activityId' => $activity->getUuid(),\n 'followupData' => $followupData,\n 'userId' => $user->getUuid(),\n ]);\n\n // Store data in the CRM.\n // ++add check for crm_required\n $job = new SaveActivity($activity, $followupData);\n\n if ($updatedData) {\n $job->delay(Carbon::now()->addMinutes($jobDelay));\n }\n\n dispatch($job);\n\n // Manually dispatch log for Opportunity or Prospect added\n if ($activity->hasOpportunity() || $activity->hasProspect()) {\n event(new ActivityProspectAdded(\n activity: $activity,\n eventSource: 'manually-log-crm-data'\n ));\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.\n *\n * @param ServiceInterface $service\n * @param Activity $activity\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array\n {\n $updatedData = [];\n $existingData = $activity->data()->get();\n\n // We need to delete any existing data to overwrite with latest values.\n $activity->data()->delete();\n\n $layoutEntities = $layout->entities()\n ->with('field', 'parent')\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->get();\n\n /** @var LayoutEntity $entity */\n foreach ($layoutEntities as $entity) {\n // If the user has provided a value for this entity\n if (array_key_exists($entity->id_string, $entities)) {\n $value = $entities[$entity->id_string];\n\n // Convert raw data into values that the CRM can consume.\n if ($value) {\n $value = $service->normalizeValue($entity->field->type, $value);\n }\n\n // Check the field is part of the activity-summary section.\n if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {\n // This is the internal database ID, not the external CRM ID.\n $objectId = null;\n\n switch ($entity->field->object_type) {\n case Field::OBJECT_ACCOUNT:\n $objectId = $activity->account_id;\n\n break;\n\n case Field::OBJECT_CONTACT:\n $objectId = $activity->contact_id;\n\n break;\n\n case Field::OBJECT_OPPORTUNITY:\n $objectId = $activity->opportunity_id;\n\n break;\n\n case Field::OBJECT_LEAD:\n $objectId = $activity->lead_id;\n\n break;\n\n case Field::OBJECT_TASK:\n case Field::OBJECT_EVENT:\n $objectId = $activity->id;\n\n break;\n }\n\n if ($objectId) {\n /** @var FieldData $data */\n $data = $activity->data()->create([\n 'crm_layout_entity_id' => $entity->id,\n 'crm_field_id' => $entity->crm_field_id,\n 'object_type' => $entity->field->object_type,\n 'object_id' => $objectId,\n 'value' => $value,\n ]);\n\n // Never send read-only field data to the CRM.\n if ($entity->read_only === false && $entity->is_visible) {\n $existingValue = $existingData\n ->where('crm_layout_entity_id', $entity->id)\n ->where('crm_field_id', $entity->crm_field_id)\n ->where('object_type', $entity->field->object_type)\n ->where('object_id', $objectId)\n ->first();\n\n // If the field was actually changed, we need to reflect this in the CRM too.\n if ($existingValue === null || $existingValue->value !== $value) {\n $updatedData[] = $data->id;\n }\n }\n }\n }\n }\n }\n\n return $updatedData;\n }\n\n /**\n * Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.\n *\n * @param ServiceInterface $crmService\n * @param Layout $layout\n * @param array $entities The raw entity data from user\n *\n * @return array\n */\n private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array\n {\n $fieldData = [];\n foreach ($entities as $entityId => $value) {\n // Only bother with fields that have a value.\n if ($value) {\n // Extract the entity from the UUID. Check the field is valid and part of the follow-up section.\n $entity = $layout->entities()\n ->uuid($entityId, false)\n ->whereHas('parent', function ($query) {\n $query->where('label', 'follow-up');\n })\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->first();\n\n if ($entity) {\n // Convert raw data into values that the CRM can consume.\n $value = $crmService->normalizeValue($entity->field->type, $value);\n\n // Add the field and value to the payload.\n $fieldData += [\n $entity->field->crm_provider_id => $value,\n ];\n }\n }\n }\n\n return $fieldData;\n }\n\n /**\n * @param Activity $activity\n */\n private function validateSummary(Activity $activity): void\n {\n $team = $activity->user->team;\n $crmProvider = $team->crm->provider;\n $attributes = [];\n\n $rules = [\n 'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,\n 'title' => 'string|max:250',\n 'prospects' => 'required|array',\n 'opportunity_id' => new CrmReference($crmProvider),\n 'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',\n 'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator\n 'summary' => 'max:50000',\n 'nId' => 'exists:notifications,id',\n 'crm_id' => new CrmReference($crmProvider),\n 'entities' => 'array',\n 'is_internal' => 'boolean',\n ];\n\n /** @var Layout $layout */\n $layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));\n\n // Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.\n $entities = $layout->entities()\n ->where('read_only', 0)\n ->whereHas('field', function ($query) {\n $query->where('is_selectable', 1);\n })\n ->whereHas('parent', function ($query) use ($activity) {\n if ($activity->isLoggable() === false) {\n $query->where('label', '<>', 'follow-up');\n }\n });\n\n $isInternal = $this->request->input('is_internal', false);\n\n foreach ($entities->get() as $entity) {\n $rules += $this->buildFieldValidator($entity, $isInternal);\n $attributes += $this->buildFieldMessage($entity);\n }\n\n $this->request->validate($rules, [], $attributes);\n }\n\n private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array\n {\n return [\n 'entities.' . $entity->id_string => $entity->getValidator($isInternal),\n ];\n }\n\n /**\n * @param LayoutEntity $entity\n *\n * @return array\n */\n private function buildFieldMessage(LayoutEntity $entity): array\n {\n $label = $entity->label;\n if ($label === null) {\n $label = $entity->field->label;\n }\n\n return [\n 'entities.' . $entity->id_string => $label,\n ];\n }\n\n public function search(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->debugLog(\n $user,\n 'User extracted from request',\n ['user' => $user->getId(), 'tz' => $user->getTimezone()]\n );\n\n $searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());\n\n $this->debugLog(\n $user,\n 'ActivitySearch criteria built',\n ['searchCriteria' => $searchCriteria]\n );\n\n $filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);\n\n $this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);\n\n $this->validateSearch($request, $filterSet);\n\n $this->debugLog($user, 'Request validated');\n\n $searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);\n\n /** @var Collection<Activity> $activities */\n $activities = $searchResponse['results'];\n\n $this->debugLog($user, 'Activities ES response extracted');\n\n $hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(\n $user->getTeamId(),\n TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),\n );\n\n if ($hideInternalMeetingsSetting?->getValue() === '1') {\n $activities = $activities->filter(function (Activity $activity) {\n if ($activity->is_internal && empty($activity->actual_start_time)) {\n return false;\n }\n\n return true;\n });\n }\n\n $this->debugLog($user, 'Internal meetings (?!) filtered');\n\n $this->response->getManager()\n ->parseIncludes([\n 'category',\n 'organizer.group',\n 'prospect',\n 'stage',\n 'opportunity',\n 'stats',\n 'scorecards',\n 'masterTrack',\n 'activeParticipants',\n 'notification',\n ])\n ->setSerializer(new JsonSerializer());\n\n $transformerExcludes = $this->request->input('exclude');\n if ($transformerExcludes) {\n $this->response->getManager()->parseExcludes($transformerExcludes);\n }\n\n $this->debugLog($user, 'Response Manager (?!) applied');\n\n $transformer = new ActivityTransformer();\n $transformer->setConsumer($user);\n\n $this->debugLog($user, 'Activity Transformer added');\n\n $resource = new \\League\\Fractal\\Resource\\Collection($activities, $transformer);\n $page = $searchCriteria->getPageNumber();\n\n $this->debugLog($user, 'Search criteria page number called', ['page' => $page]);\n\n $histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');\n\n $this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);\n\n return $this->response->withArray([\n 'pagination' => [\n 'total' => $searchResponse['totalHits'],\n 'current' => $page,\n 'prev' => max($page - 1, 1),\n 'next' => $page + 1,\n ],\n 'results' => $this->response->getManager()->createData($resource)->toArray(),\n 'histogram' => $histogram,\n ]);\n }\n\n private function debugLog(User $user, string $logMessage, ?array $context = []): void\n {\n // Debug for Learning People Only\n if ($user->getTeamId() !== 260) {\n return;\n }\n\n Log::notice(\n sprintf('[activity-search-controller] %s', $logMessage),\n $context\n );\n }\n\n /** @throws ValidationException */\n private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void\n {\n $rules = [\n 'exclude' => 'array',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ];\n\n if ($prefix !== null && mb_strpos($prefix, '.') !== false) {\n $rules[rtrim($prefix, '.')] = sprintf(\n 'required|array|max:%d',\n $filterSet->count()\n );\n }\n\n $validationRules = $filterSet->getValidationRules($prefix)\n ->merge($rules)\n ->all();\n\n $request->validate($validationRules);\n }\n\n public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $search = $this->updateOrCreateActivitySearch($request);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function updateActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('update', $search);\n\n $this->updateOrCreateActivitySearch($request, $search);\n\n return $this->response->withOk();\n }\n\n private function storeNamedSearchFilters(\n Collection $request,\n Search $search,\n FilterDefinitionCollection $filterSet,\n ?string $prefix = null,\n ): self {\n $arrayTypeProperties = $filterSet\n ->getPropertyTypes([\n FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,\n ])\n ->all();\n\n $supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);\n\n foreach ($supportedRequestProperties as $requestPropertyName) {\n if (! array_has($request, $requestPropertyName)) {\n continue;\n }\n\n /** @var string|string[] $propertyValue */\n $propertyValue = array_get($request, $requestPropertyName);\n $propertyName = $prefix === null\n ? $requestPropertyName\n : mb_substr($requestPropertyName, mb_strlen($prefix));\n\n $isArrayType = array_has($arrayTypeProperties, $propertyName);\n\n if (! $isArrayType) {\n /** @var string $requestPropertyValue */\n\n $search->filters()->updateOrCreate(\n [\n 'filter' => $propertyName,\n ],\n [\n 'value' => $propertyValue,\n ]\n );\n\n continue;\n }\n\n /** @var string[] $requestPropertyValue */\n\n /** @var SearchFilter[]|Collection $existingFilterValues */\n $existingFilterValuesKeyed = $search->filters()\n ->where('filter', $propertyName)\n ->get()\n ->keyBy('id');\n\n // Iterate over values provided as request parameters\n foreach ($propertyValue as $value) {\n /** @var SearchFilter|null $valueFilter */\n $valueFilter = $search->filters()\n ->where(\n [\n 'filter' => $propertyName,\n 'value' => $value,\n ]\n )\n ->first();\n\n if ($valueFilter !== null) {\n // Remove filter value pair from list to be deleted\n $existingFilterValuesKeyed->forget($valueFilter->id);\n } else {\n // Add new filter/value pair\n $search->filters()->updateOrCreate([\n 'filter' => $propertyName,\n 'value' => $value,\n ]);\n }\n }\n\n // Delete filter value pairs for this filter that no longer exist in request parameters\n foreach ($existingFilterValuesKeyed as $existingFilter) {\n $existingFilter->delete();\n }\n }\n\n /** @var Collection<int, SearchFilter> $filtersKeyed */\n $filtersKeyed = $search->filters()->get()->keyBy('filter');\n\n // wipe removed filters from this search\n foreach ($filtersKeyed as $filterName => $filter) {\n if (array_has($request, $prefix . $filterName)) {\n continue;\n }\n\n // Remove all filter values for this filter\n $search->filters()->where('filter', $filterName)->delete();\n }\n\n return $this;\n }\n\n /**\n * @throws AuthorizationException\n */\n public function fetchActivitySearch(\n Search $search,\n Request $request,\n SearchTransformer $searchTransformer,\n ): JsonResponse {\n $this->authorize('view', $search);\n\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem(\n $search,\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse\n {\n /** @var User $user */\n $user = $request->user();\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection(\n $user->searches()->get(),\n $searchTransformer\n ->withConsumer($user)\n );\n }\n\n /**\n * Deletes a saved search\n *\n * @param Request $request\n * @param Search $search\n *\n * @throws Exception\n *\n * @return JsonResponse\n */\n public function deleteActivitySearch(Request $request, Search $search): JsonResponse\n {\n $this->authorize('delete', $search);\n\n // Orphan any AutomatedReports that use this search\n $search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);\n\n // Delete filters and the search itself\n $search->filters()->delete();\n $search->delete();\n\n return $this->response->withOk();\n }\n\n public function live(Request $request, ElasticActivityRepository $repository): JsonResponse\n {\n $user = $this->getUserFromRequest($request);\n\n $this->request->validate([\n 'sort_direction' => 'in:asc,desc',\n 'limit' => 'integer|min:1|max:50',\n 'page' => 'integer|min:1',\n ]);\n\n $activities = $repository->getLiveCoachingEligibleActivities(\n user: $user,\n lookBackMinutes: self::LOOK_BACK,\n limit: (int) $this->request->input('limit', 25),\n page: (int) $this->request->input('page', 1),\n sortBy: ['actual_start_time', 'scheduled_start_time'],\n sortDirection: (string) $this->request->input('sort_direction', 'asc'),\n );\n\n $this->response\n ->getManager()\n ->parseIncludes(['organizer.group', 'prospect'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($activities, new ActivityTransformer());\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function show(Activity $activity, ActivityService $activityService): JsonResponse\n {\n $this->authorize('show', $activity);\n\n $user = $activity->getUser();\n $team = $user->getTeam();\n\n // Sync the opportunity with the latest data if possible.\n if ($activity->opportunity_id) {\n try {\n $crmService = $this->providerRegistry->get($team->crm->provider);\n\n if (! $user->isCrmRequired()) {\n $crmService->setUser($team->getOwner());\n } else {\n $crmService->setUser($user);\n }\n\n $crmService->syncOpportunity($activity->opportunity->crm_provider_id);\n } catch (Exception $exception) {\n // Move on.\n }\n }\n\n $activityData = $activityService->getActivityData($this->request->user(), $activity);\n\n return response()->json($activityData);\n }\n\n public function createRecording(Activity $activity)\n {\n $this->authorize('record', $activity);\n\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Tell Twilio to start recording this activity.\n if ($activity->recording_state === Activity::RECORDING_OFF) {\n $job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withCreated();\n }\n\n return $this->response->errorGone('Activity is already recording.');\n }\n\n public function updateRecording(Request $request, Activity $activity)\n {\n $this->authorize('record', $activity);\n\n $request->validate([\n 'preference' => 'boolean',\n 'state' => [\n 'string',\n Rule::in([\n Activity::RECORDING_IN_PROGRESS,\n Activity::RECORDING_PAUSED,\n ]),\n ],\n ]);\n\n if ($request->has('state')) {\n if ($activity->hasRecordingReasonComplianceRestricted()) {\n return $this->response->errorGone('Recording this number has been disabled by your organization.');\n }\n\n // Toggle the recording state between paused and resumed.\n if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {\n $job = (new ToggleRecording($activity, $request->input('state')))\n ->onQueue(Constants::QUEUE_CONFERENCES);\n\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Recording is not toggleable.');\n }\n\n if ($request->has('preference')) {\n $activity->update([\n 'recording_preference' => $request->input('preference') ? 1 : 0,\n ]);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorWrongArgs('Something went wrong');\n }\n\n public function stopRecording(Activity $activity)\n {\n $this->authorize('stopRecord', $activity);\n\n // Tell Twilio to stop recording this activity.\n if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {\n $job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);\n dispatch($job);\n\n return $this->response->withOk();\n }\n\n return $this->response->errorGone('Activity is not recording.');\n }\n\n /**\n * Add activity to this user's favorites playlist\n *\n * @throws AuthorizationException\n */\n public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse\n {\n $this->authorize('favorite', $activity);\n\n $user = $this->getUserFromRequest($this->request);\n $favorite = $activity->wasFavoritedBy($user);\n $name = $activity->activity_title ?? '';\n\n // It needs to check at least one record.\n if (! $favorite) {\n $favoritePlaylist = $user->favoritePlaylist();\n\n $playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(\n $activity,\n $user,\n $favoritePlaylist\n );\n\n if ($playlistActivity !== null) {\n $playlistActivity->update(\n // Just update, don't sort.\n ['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],\n );\n } else {\n $playlistActivity = $activity->playlistActivities()->create([\n 'playlist_id' => $favoritePlaylist->getId(),\n 'user_id' => $user->getId(),\n 'start_time' => 0,\n 'name' => mb_strimwidth($name, 0, 100),\n ]);\n // Sort it on top.\n $playlistActivity->update(\n [\n 'sort' => $playlistActivityRepository->calculateNewSortOrder(\n null,\n $playlistActivity,\n ),\n ],\n );\n }\n\n $playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);\n\n return new JsonResponse([], JsonResponse::HTTP_CREATED);\n }\n\n return new JsonResponse(\n [\n 'error' => [\n 'code' => AbstractResponse::CODE_CONFLICT,\n 'http_code' => JsonResponse::HTTP_CONFLICT,\n 'message' => 'Resource Already Exists',\n ],\n ],\n JsonResponse::HTTP_CONFLICT,\n );\n }\n\n /**\n * Remove activity from this user's favorites playlist\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unfavorite(Activity $activity)\n {\n $user = $this->request->user();\n\n $favorites = $activity->favoritedBy($user);\n\n if ($favorites && $favorites->isEmpty()) {\n return $this->response->errorNotFound('Favorite not found.');\n }\n\n $this->authorize('unfavorite', [$activity, $favorites]);\n\n // When you unfavorite an activity,\n // it should remove all the activities in it, including snippets.\n $isDeleted = $favorites->each(function ($favorite) {\n $favorite->forceDelete();\n });\n\n if ($isDeleted) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not remove favorite.');\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function notify(Activity $activity)\n {\n $this->authorize('notify', $activity);\n\n $user = $this->request->user();\n\n $existingNotification = $activity->availabilityNotifications()\n ->where('user_id', $user->id)\n ->exists();\n\n if ($existingNotification) {\n return $this->response->errorWrongArgs('Notification is already configured.');\n }\n\n $notification = Activity\\AvailabilityNotification::create([\n 'user_id' => $user->id,\n 'activity_id' => $activity->id,\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($notification, new AvailabilityNotificationTransformer());\n }\n\n /**\n * @param Activity $activity\n * @param Activity\\AvailabilityNotification $notification\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function unnotify(Activity $activity, Activity\\AvailabilityNotification $notification)\n {\n $this->authorize('unnotify', [$activity, $notification]);\n\n if ($notification->sent_at || $notification->delete()) {\n return $this->response->withNoContent();\n }\n\n return $this->response->errorGone('Could not delete notification.');\n }\n\n public function play(Request $request, Activity $activity)\n {\n $this->authorize('stream', $activity);\n\n $request->validate([\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $activity->plays()->create([\n 'user_id' => $user->getId(),\n 'start_time' => $request->input('start_time'),\n ]);\n\n return $this->response->withCreated();\n }\n\n /**\n * @param Activity $activity\n *\n * @return mixed\n */\n public function comment(Activity $activity)\n {\n return $this->newComment($activity);\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @return mixed\n */\n public function replyComment(Activity $activity, Comment $comment)\n {\n return $this->newComment($activity, $comment);\n }\n\n /**\n * @param Activity $activity\n * @param Comment|null $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n protected function newComment(Activity $activity, ?Comment $comment = null)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n 'type' => 'integer|between:0,3',\n 'visibility' => sprintf('nullable|integer|between:1,%d', count(Comment::getVisibilityLevels())),\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n $threadStartId = null;\n if ($comment) {\n $threadStartId = $comment->thread_start_id ?: $comment->id;\n }\n\n try {\n $newComment = Comment::create([\n 'parent_comment_id' => $comment->id ?? null,\n 'thread_start_id' => $threadStartId,\n 'activity_id' => $activity->id,\n 'user_id' => $this->request->user()->id,\n 'comment' => trim($this->request->input('comment')),\n 'start_time' => $this->request->input('start_time', 0),\n 'end_time' => $this->request->input('end_time', 0),\n 'type' => $this->request->input('type', Comment::TYPE_NEUTRAL),\n 'visibility' => $this->request->input('visibility', Comment::VISIBILITY_PUBLIC),\n ]);\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($newComment, new ActivityCommentTransformer());\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not create comment.' . $exception->getMessage());\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function updateComment(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'comment' => 'required|between:1,5000',\n //'start_time' => 'numeric|between:0,'.$activity->duration,\n //'end_time' => 'required_with:start_time|greater_than_or_equal:start_time|numeric|between:0,'.$activity->duration,\n ]);\n\n try {\n $comment->update([\n 'comment' => trim($this->request->input('comment')),\n ]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment.');\n }\n }\n\n public function updateCommentVisibility(Activity $activity, Comment $comment)\n {\n $this->authorize('comment', [$activity, $comment]);\n\n $this->request->validate([\n 'visibility' => sprintf('integer|between:1,%d', count(Comment::getVisibilityLevels())),\n ]);\n\n $visibility = $this->request->input('visibility');\n\n if ($comment->parent !== null) {\n return $this->response->errorWrongArgs('Comment visibility can only be updated on top level comments.');\n }\n\n try {\n $this->activityCommentService->updateCommentVisibility($comment, $visibility);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withOk();\n } catch (Exception $exception) {\n Sentry::captureException($exception);\n\n return $this->response->errorInternalError('Could not update comment\\'s visibility.');\n }\n }\n\n /**\n * @param Activity $activity\n * @param Comment $comment\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function deleteComment(Activity $activity, Comment $comment)\n {\n $this->authorize('deleteComment', [$activity, $comment]);\n\n // Delete comment and any children.\n $comment->delete();\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function fetchComments()\n {\n $user = $this->request->user();\n $this->request->validate([\n 'forUserId' => 'uuid:users,team_id,' . $user->team_id,\n 'types' => 'array',\n 'types.*' => 'integer|between:0,3',\n ]);\n $forUser = null;\n\n $types = [Comment::TYPE_NEUTRAL, Comment::TYPE_GAME_CHANGER, Comment::TYPE_POSITIVE];\n $user = $this->request->user();\n if ($this->request->has('forUserId')) {\n $forUser = $user->team->users()->uuid($this->request->input('forUserId'));\n }\n\n $comments = Comment::query()\n ->whereHas('activity', static function (Builder $builder) use ($user, $forUser): void {\n $builder\n // I left feedback on my own activity; or\n ->where('activities.user_id', $user->getId());\n if ($forUser) {\n // I left feedback on any activity for this user.\n $builder->orWhere([\n 'user_id' => $user->getId(),\n 'activities.user_id' => $forUser->getId(),\n ]);\n }\n })\n ->whereIn('type', $this->request->input('types', $types))\n ->orderBy('created_at', 'desc')\n ->get();\n\n $this->response\n ->getManager()\n ->parseIncludes(['activity', 'user'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($comments, new ActivityCommentTransformer());\n }\n\n public function deleteCoachingFeedback(Activity $activity, CoachingFeedback $coachingFeedback)\n {\n $this->authorize('deleteCoachingFeedback', [$activity, $coachingFeedback]);\n $activity = $coachingFeedback->getActivity();\n\n if ($coachingFeedback->delete()) {\n event(new UpdateSingleEntity(\n entityId: $activity->getId(),\n updateTarget: UpdateTargetEnum::ACTIVITY,\n purpose: 'delete-coaching-feedback',\n ));\n\n return $this->response->withOk();\n }\n\n return $this->response->withError('Delete operation failed. Contact support.', 500);\n }\n\n /**\n * Add new or update Coaching feedback\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n * @throws \\Illuminate\\Validation\\ValidationException\n *\n * @return mixed\n */\n public function putCoachingFeedback(Request $request, Activity $activity)\n {\n $user = $request->user();\n\n if (! $user instanceof User) {\n abort(403);\n }\n $teamId = $user->getTeamId();\n\n $this->authorize('coach', $activity);\n\n $this->request->validate([\n 'coach_id' => 'required|uuid:users,team_id,' . $teamId,\n 'coachee_id' => 'required|uuid:users,team_id,' . $teamId,\n 'visibility' => ['required', Rule::in(CoachingFeedback::VISIBILITIES)],\n 'coaching_sections.*.uuid' => 'required|uuid:coaching_sections',\n 'coaching_sections.*.score' => ['required', Rule::in(CoachingSectionFeedback::SCORES)],\n 'coaching_sections.*.summary' => 'string|max:10000',\n 'coaching_sections.*.criteria.*.uuid' => 'required|uuid:coaching_section_criteria',\n 'coaching_sections.*.criteria.*.note' => 'required|string|max:10000',\n 'sharedWithUsers' => [\n 'required_if:visibility,' . CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS,\n 'array',\n ],\n 'sharedWithUsers.*' => [\n 'uuid:users,team_id,' . $teamId,\n ],\n ]);\n\n /** @var User $coach */\n $coach = User::uuid($this->request->input('coach_id'));\n /** @var User $coachee */\n $coachee = User::uuid($this->request->input('coachee_id'));\n $coachingSectionFeedbacks = $this->request->input('coaching_sections');\n\n $previousRecord = $this->coachingFeedbackRepository->getOneForActivityByCoacheeAndCoach(\n $coachee->getId(),\n $coach->getId(),\n $activity->getId()\n );\n $recordIsNew = false;\n if ($previousRecord === null) {\n $recordIsNew = true;\n }\n\n if (! $coachee->isSameTeamId($coach)) {\n return $this->response->errorForbidden('User not member of your team.');\n }\n\n if (! is_array($coachingSectionFeedbacks) || count($coachingSectionFeedbacks) < 1) {\n return $this->response->withError('At least one Coaching Framework Section shall be scored.', 422);\n }\n\n if (! $activity->participants()->where('participants.user_id', $coachee->id)->exists()) {\n return $this->response->withError('Coached user did not participate activity.', 422);\n }\n\n $visibility = $this->request->input('visibility');\n\n $shouldSendNotification = $recordIsNew;\n if ($recordIsNew === false && $visibility !== $previousRecord->getVisibility()) {\n $shouldSendNotification = true;\n }\n\n /**\n * Create CoachingFeedback\n *\n * @var CoachingFeedback $coachingFeedback\n */\n $coachingFeedback = $activity->coachingFeedbacks()->updateOrCreate(\n [\n 'coach_id' => $coach->id,\n 'coachee_id' => $coachee->id,\n ],\n [\n 'framework_id' => $activity->category->id,\n 'visibility' => $visibility,\n ]\n );\n\n $sharedUserIds = [];\n if ($visibility === CoachingFeedback::VISIBLE_TO_SPECIFIC_USERS) {\n foreach ($this->request->input('sharedWithUsers') as $sharedWithUserUuid) {\n /** @var User $user */\n $user = User::uuid($sharedWithUserUuid);\n $sharedUserIds[] = $user->getId();\n }\n }\n\n $syncResult = $coachingFeedback->customAccessUsers()->sync($sharedUserIds);\n\n $scores = [];\n\n\n /**\n * Create CoachingSectionsFeedbacks.\n *\n * @var CoachingSectionFeedback $coachingSectionFeedback\n */\n foreach ($coachingSectionFeedbacks as $coachingSectionFeedbackInput) {\n $coachingSection = CoachingSection::uuid($coachingSectionFeedbackInput['uuid']);\n $coachingSectionFeedback = $coachingFeedback->sectionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_id' => $coachingSection->id,\n ],\n [\n 'score' => array_get($coachingSectionFeedbackInput, 'score'),\n 'summary' => array_get($coachingSectionFeedbackInput, 'summary') ?? '',\n ]\n );\n\n $scores[] = array_get($coachingSectionFeedbackInput, 'score');\n\n $criteria = array_get($coachingSectionFeedbackInput, 'criteria');\n if (is_array($criteria) && ! empty($criteria)) {\n foreach ($criteria as $criteriaFeedbackInput) {\n $coachingSectionFeedback->criterionFeedbacks()->updateOrCreate(\n [\n 'coaching_section_criterion_id' => CoachingSectionCriterion::uuid(array_get($criteriaFeedbackInput, 'uuid'))\n ->id,\n ],\n ['note' => array_get($criteriaFeedbackInput, 'note')],\n );\n }\n }\n }\n\n $coachingFeedback->average_score = array_sum($scores) / count($scores);\n\n if ($recordIsNew === false && $coachingFeedback->getAverageScore() !== $previousRecord->getAverageScore()) {\n $shouldSendNotification = true;\n }\n if (! empty($syncResult['attached']) || ! empty($syncResult['detached']) || ! empty($syncResult['updated'])) {\n $shouldSendNotification = true;\n }\n\n $coachingFeedback->save();\n // ensure updated at for coaching feedback on section feedback summary added.\n $coachingFeedback->touch();\n\n if ($shouldSendNotification) {\n event(new Coached($coachingFeedback));\n }\n\n Datadog::increment('jiminny.activity.score.update', 1, ['company' => $activity->user->team->slug]);\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n $coachingFeedbackTransformer = new CoachingFeedbackTransformer();\n $coachingFeedbackTransformer->setConsumer($this->getUserFromRequest($request));\n\n return $this->response->withItem($coachingFeedback, $coachingFeedbackTransformer);\n }\n\n\n /**\n * Retrieve category criteria for coaching.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachingSections(Activity $activity)\n {\n $this->authorize('coach', $activity);\n\n if ($activity->category === null) {\n return $this->response->errorUnprocessable('Category has not yet been assigned.');\n }\n\n $criteria = $activity\n ->category\n ->coachingSections()\n ->where('is_enabled', 1)\n ->orderBy('sequence', 'asc');\n\n $this->response\n ->getManager()\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withCollection($criteria->get(), new CoachingSectionsTransformer());\n }\n\n /**\n * @throws AuthorizationException\n * @throws ValidationException\n *\n * @return mixed\n */\n public function addToPlaylist(Activity $activity, PlaylistTrackFactoryInterface $playlistTrackFactory)\n {\n $this->request->validate([\n 'playlists' => 'required|array',\n 'playlists.*' => 'uuid:playlists',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'name' => 'required|max:100',\n ]);\n\n $this->authorize('addToPlaylist', [$activity, $this->request->input('playlists')]);\n\n $startTime = $this->request->input('start_time');\n $endTime = $this->request->input('end_time');\n $name = $this->request->input('name');\n /** @var User $user */\n $user = $this->request->user();\n\n // Get playlist by uuid.\n foreach ($this->request->input('playlists') as $playlistId) {\n // Pull out the playlist model.\n $playlist = Playlist::uuid($playlistId);\n\n $playlistTrackFactory->createTrack($playlist, $user, [\n 'name' => $name,\n 'activity' => $activity,\n 'start_time' => $startTime,\n 'end_time' => $endTime,\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function share(Request $request, Activity $activity): JsonResponse\n {\n $this->authorize('share', $activity);\n\n $request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'recipients.*.type' => 'in:user,group',\n 'recipients.*.id' => 'string|max:40',\n 'share' => 'string|max:255',\n ]);\n\n $user = $request->user();\n\n $recipients = $request->get('recipients');\n $users = $this->userService->convertRecipientsToUsers($user, $recipients);\n\n $shareData = [\n 'from_user_id' => $user->id,\n 'note' => $request->input('note'),\n 'start_time' => $request->input('start_time'),\n 'end_time' => $request->input('end_time'),\n ];\n\n // Create a share object against a notification provider channel\n if ($request->input('share')) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'notification_provider_channel' => $request->input('share'),\n ]\n )\n );\n\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n\n // Create a share object against each recipient\n foreach ($users as $recipient) {\n /** @var Share $share */\n $share = $activity->shares()->create(\n array_merge(\n $shareData,\n [\n 'to_user_id' => $recipient->id,\n ]\n )\n );\n\n // If parent_share_id has been selected yet\n if (! isset($shareData['parent_share_id'])) {\n // All subsequent shares need to reference this row as parent_share_id\n $shareData['parent_share_id'] = $share->id;\n }\n }\n\n return $this->response->withOk();\n }\n\n /**\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function coachRequest(Activity $activity)\n {\n $this->authorize('coachRequest', $activity);\n\n $this->request->validate([\n 'note' => 'string|max:1000',\n 'start_time' => 'numeric|between:0,' . $activity->duration,\n 'end_time' => 'nullable|greater_than_or_equal:start_time|numeric|between:0,' . $activity->duration,\n 'coachers.*.type' => 'required|in:user',\n 'coachers.*.id' => 'required',\n ]);\n\n $coachers = $this->request->get('coachers');\n $user = $this->request->user();\n $users = $this->userService->convertRecipientsToUsers($user, $coachers);\n\n foreach ($users as $coacher) {\n CoachRequest::create([\n 'user_id' => $coacher->id,\n 'activity_id' => $activity->id,\n 'note' => $this->request->get('note'),\n 'start_time' => $this->request->get('start_time'),\n 'end_time' => $this->request->get('end_time'),\n ]);\n }\n\n return $this->response->withOk();\n }\n\n public function createActivityTopicTriggers(Activity $activity, LoggerInterface $logger): HttpFoundation\\JsonResponse\n {\n $this->authorize('analyzeTopicTriggers', $activity);\n\n if (! $activity->hasTranscription()) {\n return new HttpFoundation\\JsonResponse(\n [\n 'error' => 'Transcription not found.',\n ],\n JsonResponse::HTTP_NOT_FOUND\n );\n }\n\n $logger->info(__METHOD__ . ': queued for analysis', [\n 'activity' => $activity->id_string,\n ]);\n\n dispatch(new ActivityAnalytics\\Job\\AnalyzeActivityTopicTriggers($activity));\n\n return new HttpFoundation\\JsonResponse(null, JsonResponse::HTTP_CREATED);\n }\n\n public function fetchActivityTopicTriggers(\n Activity $activity,\n LoggerInterface $logger,\n ActivityTopicTriggerTransformer $transformer\n ): HttpFoundation\\JsonResponse {\n $this->authorize('fetchTopicTriggers', $activity);\n\n $logger->debug(__METHOD__, [\n 'activity' => $activity->id_string,\n ]);\n\n if (! $activity->isProcessed()) {\n return new HttpFoundation\\JsonResponse([]);\n }\n\n $payload = [];\n\n if ($activity->hasTopicTriggers()) {\n $payload = $activity->getTopicTriggersSorted()\n ->map(\n static fn (Activity\\TopicTrigger $activityTopicTrigger): array\n => $transformer->transform($activityTopicTrigger)\n )\n ->values()\n ->all();\n }\n\n return new HttpFoundation\\JsonResponse($payload);\n }\n\n /**\n * @param Activity $activity\n * @param StatsTransformer $statsTransformer\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function stats(Activity $activity, StatsTransformer $statsTransformer)\n {\n $this->authorize('stream', $activity);\n\n if (! $activity->hasTranscription()) {\n return $this->response->errorNotFound('Waveform data is not yet generated.');\n }\n\n $this->response\n ->getManager()\n ->parseIncludes(['wavedata'])\n ->setSerializer(new JsonSerializer());\n\n return $this->response->withItem($activity, $statsTransformer);\n }\n\n public function destroy(Activity $activity)\n {\n $this->authorize('delete', $activity);\n\n $activity->delete();\n\n \\Log::info('Soft delete activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);\n\n return $this->response->withNoContent();\n }\n\n public function note(Activity $activity)\n {\n $this->authorize('note', $activity);\n\n $this->request->validate([\n 'note' => 'required|min:1|max:2000',\n 'time' => 'required|numeric|min:0|max:86400',\n ]);\n\n $note = $this->request->input('note');\n $time = $this->request->input('time');\n\n $this->activityService->setActivity($activity);\n $this->activityService->takeNote($this->getUser(), $note, $time);\n\n return $this->response->withCreated();\n }\n\n /**\n * Mark an activity as private.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPrivate(Activity $activity)\n {\n $this->authorize('markAsPrivate', $activity);\n\n if ($activity->is_private === false) {\n $activity->is_private = true;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * Mark an activity as public.\n *\n * @param Activity $activity\n *\n * @throws AuthorizationException\n *\n * @return mixed\n */\n public function markAsPublic(Activity $activity)\n {\n $this->authorize('markAsPublic', $activity);\n\n if ($activity->is_private) {\n $activity->is_private = false;\n $activity->save();\n\n return $this->response->withOk();\n }\n\n return $this->response->withNoContent();\n }\n\n /**\n * @throws LogicException\n */\n public function fetchCloudFrontS3MediaKeys(Activity $activity, PlaybackService $playbackService): JsonResponse\n {\n $masterTrack = $activity->masterTrack()->first();\n\n if (! $masterTrack instanceof Track) {\n throw new LogicException(sprintf('Master track not found for activity \"%s\"', $activity->getUuid()));\n }\n\n return $this->response->withArray(\n $playbackService->generateCookies(\n $masterTrack,\n $this->request->ip(),\n ),\n );\n }\n\n /**\n * @throws ValidationException\n */\n private function updateOrCreateActivitySearch(Request $request, ?Search $search = null): Search\n {\n $request->validate([\n 'name' => 'required|string|min:2|max:100',\n ]);\n\n $user = $this->getUserFromRequest($request);\n\n $searchName = $request->input('name');\n\n if ($search !== null) {\n $search->update([\n 'name' => $searchName,\n ]);\n\n return $search;\n }\n\n $request->validate([\n 'filters' => ['required', 'array', new MultidimensionalArrayMaxCharRule(limit: 255)],\n 'nudges' => 'array|max:' . count(Nudge::MAP_CHANNEL),\n 'nudges.*.channel' => 'required|in:' . implode(',', Nudge::MAP_CHANNEL),\n 'nudges.*.frequency' => 'required|in:' . implode(',', Nudge::MAP_FREQUENCY),\n 'nudges.*.expiresAt' => [\n 'required',\n 'date',\n 'after:today',\n 'before_or_equal:' . now()->addYear()->format('Y-m-d'),\n ],\n ]);\n\n $searchCriteria = Criteria::createFromRequest(\n Collection::make($request->input('filters', []))->all(),\n $user->getTimezone()\n );\n\n $filterSet = $this->activitySearch->getOnDemandPageFilterSet($searchCriteria, $user);\n $this->validateSearch($request, $filterSet, 'filters.');\n\n /** @var Search $search */\n $search = Search::create([\n 'name' => $searchName,\n 'uuid' => Uuid::uuid4()->toString(),\n 'user_id' => $user->getId(),\n ]);\n\n Collection::make($request->input('nudges', []))\n ->each(fn (array $attributes): Nudge => $this->nudgeFactory->createNudge($search, $attributes));\n\n $this->storeNamedSearchFilters(Collection::make($request->all()), $search, $filterSet, 'filters.');\n\n return $search;\n }\n\n private function resolveAccount(\n Team $team,\n Contact $contact,\n ServiceInterface $crmService,\n array $prospects,\n ): ?Account {\n $this->logger->info('Resolving account from contact');\n $account = $contact->getAccount();\n\n if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS)) {\n $this->logger->info('Team does not have feature to link activity to multiple prospects');\n\n return $account;\n }\n\n $this->logger->info('Resolving account from prospect data');\n $accountData = array_filter(\n $prospects,\n static fn (array $prospectData): bool => $prospectData['type'] === 'account'\n );\n\n if (! empty($accountData)) {\n $this->logger->info('Found account data in prospects');\n $accountData = reset($accountData);\n\n $account = $team->crm->accounts()->where('crm_provider_id', $accountData['id'])->first();\n\n if (! $account instanceof Account) {\n $this->logger->info('Account not found in database, syncing from CRM');\n $account = $crmService->syncAccount($accountData['id']);\n }\n }\n\n $this->logger->info('Resolved account', ['account' => $account->getId()]);\n\n return $account;\n }\n}","role_description":"text entry area","is_enabled":true,"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":"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":"AXStaticText","text":"1","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.015277778,"height":0.02111111},"on_screen":false,"role_description":"text"},{"role":"AXStaticText","text":"51","depth":4,"bounds":{"left":0.0,"top":0.0,"width":0.02013889,"height":0.02111111},"on_screen":false,"role_description":"text"}]...
|
4682094652752259413
|
-8385861013499898732
|
visual_change
|
accessibility
|
NULL
|
Project: faVsco.js, menu
pipedrive-sdk-poc, menu
S Project: faVsco.js, menu
pipedrive-sdk-poc, 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…
<?php
namespace Jiminny\Http\Controllers\API;
use Carbon\Carbon;
use ChaseConey\LaravelDatadogHelper\Datadog;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\In;
use Illuminate\Validation\ValidationException;
use InvalidArgumentException;
use Jiminny\Component\ActivityAnalytics;
use Jiminny\Component\ActivitySearch;
use Jiminny\Component\ActivitySearch\FilterDefinitionCollection;
use Jiminny\Component\PlaybackPage\Comments\Services\ActivityCommentService;
use Jiminny\Component\Queue\Constants;
use Jiminny\Contracts\ES\Events\UpdateSingleEntity;
use Jiminny\Contracts\ES\UpdateTargetEnum;
use Jiminny\Contracts\Nudge\NudgeFactoryInterface;
use Jiminny\Contracts\Playlist\PlaylistTrackFactoryInterface;
use Jiminny\Contracts\Repositories\PlaylistActivityRepository;
use Jiminny\Contracts\Services\Crm\ServiceInterface;
use Jiminny\Enums\TeamSetting;
use Jiminny\Events\Activities\AiAutomation\ActivityProspectAdded;
use Jiminny\Events\Activities\Coaching\Coached;
use Jiminny\Contracts\Services\Crm\SupportsObjectTypeParseInterface;
use Jiminny\Exceptions\LogicException;
use Jiminny\Exceptions\SocialAccountTokenInvalidException;
use Jiminny\Http\Controllers\API\BaseController as Controller;
use Jiminny\Http\Controllers\CommentContextInterface;
use Jiminny\Http\Responses\Api\AbstractResponse;
use Jiminny\Http\Responses\Api\Response;
use Jiminny\Http\Serializers\JsonSerializer;
use Jiminny\Http\Transformers\ActivityCommentTransformer;
use Jiminny\Http\Transformers\ActivityTopicTriggerTransformer;
use Jiminny\Http\Transformers\ActivityTransformer;
use Jiminny\Http\Transformers\AvailabilityNotificationTransformer;
use Jiminny\Http\Transformers\CoachingFeedbackTransformer;
use Jiminny\Http\Transformers\CoachingSectionsTransformer;
use Jiminny\Http\Transformers\SearchTransformer;
use Jiminny\Http\Transformers\StatsTransformer;
use Jiminny\Jobs\Crm\SaveActivity;
use Jiminny\Jobs\Crm\UpdateStage;
use Jiminny\Jobs\Telephony\StartRecording;
use Jiminny\Jobs\Telephony\StopRecording;
use Jiminny\Jobs\Telephony\ToggleRecording;
use Jiminny\Models\Account;
use Jiminny\Models\Activity;
use Jiminny\Models\Activity\CoachRequest;
use Jiminny\Models\Activity\Comment;
use Jiminny\Models\Activity\Search;
use Jiminny\Models\Activity\SearchFilter;
use Jiminny\Models\Activity\Share;
use Jiminny\Models\CoachingFeedback;
use Jiminny\Models\CoachingSection;
use Jiminny\Models\CoachingSectionCriterion;
use Jiminny\Models\CoachingSectionFeedback;
use Jiminny\Models\Contact;
use Jiminny\Models\Crm\Field;
use Jiminny\Models\Crm\FieldData;
use Jiminny\Models\Crm\Layout;
use Jiminny\Models\Crm\LayoutEntity;
use Jiminny\Models\Feature\FeatureEnum;
use Jiminny\Models\LanguageDialect;
use Jiminny\Models\Lead;
use Jiminny\Models\Nudge;
use Jiminny\Models\PlaybookCategory;
use Jiminny\Models\Playlist;
use Jiminny\Models\Stage;
use Jiminny\Models\Team;
use Jiminny\Models\Track;
use Jiminny\Models\User;
use Jiminny\Repositories\CoachingFeedbackRepository;
use Jiminny\Repositories\ElasticActivityRepository;
use Jiminny\Repositories\TeamRepository;
use Jiminny\Rules\CrmReference;
use Jiminny\Rules\MultidimensionalArrayMaxCharRule;
use Jiminny\Services\ActivityService;
use Jiminny\Services\Crm\ProviderRegistry;
use Jiminny\Services\PlaybackService;
use Jiminny\Services\UserService;
use Jiminny\VO\Repository\OnDemandActivitySearch\Criteria;
use Psr\Log\LoggerInterface;
use Ramsey\Uuid\Uuid;
use Sentry;
use Symfony\Component\HttpFoundation;
final class ActivityController extends Controller implements CommentContextInterface
{
// Number of minutes to look back on activities. i.e. a timeout on activity duration.
private const int LOOK_BACK = 180;
public function __construct(
private ProviderRegistry $providerRegistry,
private ActivityService $activityService,
Response $response,
private UserService $userService,
private ActivitySearch\Service\ActivitySearch $activitySearch,
private NudgeFactoryInterface $nudgeFactory,
private ActivityCommentService $activityCommentService,
private LoggerInterface $logger,
private readonly CoachingFeedbackRepository $coachingFeedbackRepository,
private readonly TeamRepository $teamRepository,
) {
parent::__construct($response);
}
public static function getCommentImplementation(): string
{
return Comment::class;
}
public function delete()
{
$this->request->validate([
'*' => 'uuid:activities',
]);
$deletedIds = [];
foreach ($this->request->all() as $activityId) {
$activity = Activity::idOrUuId($activityId);
try {
if ($this->authorize('delete', $activity)) {
$activity->delete();
$deletedIds[] = $activityId;
\Log::info('Soft deleted activity ' . $activity->id_string . ' by user ' . $this->getUser()->id);
}
} catch (AuthorizationException $authorizationException) {
// They didn't have permission.
}
}
return $this->response->withArray($deletedIds);
}
public function update(Request $request, Activity $activity)
{
$this->authorize('updateMetadata', $activity);
$request->validate([
'title' => 'string|max:250',
'category_id' => 'uuid:playbook_categories',
'language' => [
new In(
LanguageDialect::query()
->with('language')
->cursor()
->map(static function (LanguageDialect $languageDialect): string {
return $languageDialect->getLanguageLocale();
})
->all()
),
],
]);
if ($request->has('title')) {
$activity->title = $request->input('title');
}
if ($request->has('category_id')) {
$category = PlaybookCategory::uuid($request->input('category_id'));
if ($category->playbook->team_id !== $request->user()->team_id) {
return $this->response->errorNotFound('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
if ($request->has('language')) {
if (! $activity->isInProgress()) {
return $this->response->withError(
'Activity language can only be set while the meeting is in progress.',
400
);
}
$activity->setLanguageCode($request->input('language'));
}
$activity->save();
return $this->response->withOk();
}
// XXX: This should be merged with the update method.
/**
* @param Activity $activity
*
* @throws AuthorizationException
* @throws SocialAccountTokenInvalidException
*
* @return mixed
*/
public function summarize(Activity $activity): mixed
{
$this->logger->info('[Log Activity] Summarizing activity ', [
'activityId' => $activity->getUuid(),
'payload' => $this->request->all(),
]);
$this->authorize('update', $activity);
$this->logger->info('[Log Activity] Validating summary');
// Validate the payload.
$this->validateSummary($activity);
// All objects must belong to this team.
/** @var User $user */
$user = $this->request->user();
$team = $user->getTeam();
$crmService = $this->providerRegistry->get($team->crm->provider);
try {
$crmUser = $user;
if ($user->isCrmRequired() === false) {
$crmUser = $team->owner;
}
$crmService->setUser($crmUser);
} catch (SocialAccountTokenInvalidException $accountTokenInvalidException) {
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($accountTokenInvalidException->getMessage());
}
$rawEntities = $this->request->input('entities');
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid(
$this->request->input('layout_id')
);
// Delay execution of CRM jobs to avoid locking issues.
$jobDelay = 0;
// If we have arrived from a notification, mark it as read.
$notificationId = $this->request->input('nId');
if ($notificationId) {
$notification = $user->unreadNotifications->where('id', $notificationId)->first();
if ($notification) {
$notification->markAsRead();
}
}
$title = $this->request->input('title');
$prospects = $this->request->input('prospects');
$opportunityId = $this->request->input('opportunity_id');
$stageId = $this->request->input('stage_id');
$categoryId = $this->request->input('category_id');
$summary = $this->request->input('summary');
$crmProviderId = $this->request->input('crm_id');
$isInternal = $this->request->input('is_internal') ?? false;
$lead = null;
$category = null;
$account = null;
$contact = null;
$opportunity = null;
$stage = null;
$callStage = null;
foreach ($prospects as $prospectData) {
$objectId = $prospectData['id'];
if ($objectId === null) {
continue;
}
$objectType = $prospectData['type'];
$this->logger->info('debug', ['prospect_data' => $prospectData]);
try {
if ($objectType === null) {
$this->logger->info('no object type');
if ($crmService instanceof SupportsObjectTypeParseInterface) {
$objectType = $crmService->parseObjectType($objectId);
}
}
switch ($objectType) {
case 'lead':
$this->logger->info('Processing lead');
/** @var Lead|null $lead */
$lead = $team->crm->leads()->where('crm_provider_id', $objectId)->first();
// Lead does not exist locally, import it.
if ($lead === null) {
$this->logger->info('Lead does not exist locally');
/** @var Lead $lead */
$lead = $crmService->syncLead($objectId);
}
$this->logger->info('Lead found', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
if ($stageId === null) {
$this->logger->info('Stage ID is null');
// If it was not provided, just assume it is the current stage.
$callStage = $lead->stage;
break;
}
$this->logger->info('Looking for stage');
// Determine if they have changed the stage.
/** @var Stage $stage */
$stage = $team->crm->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_LEAD)
->firstOrFail();
$this->logger->info('Stage found', ['stageId' => $stage->id, 'lead_stage' => $lead->stage_id]);
if ($lead->stage_id && $lead->stage_id !== $stage->id) {
$this->logger->info('Stage has changed');
// Storage current stage on activity.
$callStage = $lead->stage;
// The stage has changed, update in remote CRM.
dispatch(new UpdateStage($activity, $lead, $callStage, $stage));
$this->logger->info(
sprintf(
'[%s] User changing lead stage from %s to %s',
$crmService->getDisplayName(),
$callStage->getName(),
$stage->getName()
),
[
'user' => $user->getUuid(),
'lead' => $lead->getUuid(),
]
);
} else {
$this->logger->info('Stage has not changed');
// Stage remains as current.
$callStage = $stage;
}
break;
case 'account':
$this->logger->info('Processing account');
// If the object is not a lead, it should be an account.
$account = $team->crm->accounts()->where('crm_provider_id', $objectId)->first();
// Account does not exist locally, import it.
if ($account === null) {
$this->logger->info('Account does not exist locally');
$account = $crmService->syncAccount($objectId);
}
$this->logger->info('Account found', ['accountId' => $account->id]);
break;
case 'contact':
$this->logger->info('processing contact');
$contact = $team->crm->contacts()->where('crm_provider_id', $objectId)->first();
// Contact does not exist locally, import it.
if (! $contact instanceof Contact) {
$this->logger->info('contact does not exist locally');
$contact = $crmService->syncContact($objectId);
}
$this->logger->info('resolving account');
$account = $this->resolveAccount($team, $contact, $crmService, $prospects);
break;
}
// If they have specified an opportunity, retrieve this with stage.
if ($opportunityId) {
$this->logger->info('opportunity id is set');
$opportunity = $team->crm->opportunities()->where('crm_provider_id', $opportunityId)->first();
// Opportunity does not exist locally, import it.
if ($opportunity === null) {
$this->logger->info('opportunity does not exist locally');
$opportunity = $crmService->syncOpportunity($opportunityId);
}
if ($stageId === null) {
$this->logger->info('stage id is null');
// If it was not provided, just assume it is the current stage.
$callStage = $opportunity->stage ?? null;
} else {
$this->logger->info('looking for stage');
/** @var ?Stage $opportunityStage */
$opportunityStage = $team->crm
->stages()
->uuid($stageId, false)
->where('type', Stage::TYPE_OPPORTUNITY)
->first();
// There is a chance we still cannot import this opportunity.
if ($opportunityStage !== null && $opportunity !== null && $opportunity->stage_id !== $opportunityStage->id) {
$this->logger->info('opportunity stage has changed');
// Storage current stage on activity.
$callStage = $opportunity->stage;
dispatch(new UpdateStage($activity, $opportunity, $callStage, $opportunityStage));
$this->logger->info(
sprintf(
'[%s] User changing opportunity stage from %s to %s',
$crmService->getDisplayName(),
$callStage->name,
$opportunityStage->name
),
[
'userId' => $user->id_string,
'opportunityId' => $opportunity->id_string,
]
);
} else {
$this->logger->info('opportunity stage has not changed');
// Stage remains as current.
$callStage = $opportunityStage;
}
}
}
if ($crmProviderId) {
// Cast $crmProviderId to string otherwise it won't use database index for some records
$linkedActivity = Activity::where('crm_provider_id', (string) $crmProviderId)->first();
// Check if this activity has already been assigned to a different activity.
if ($linkedActivity && $linkedActivity->id !== $activity->id) {
throw new InvalidArgumentException(
'Sorry, the linked task has already been logged under a different call. '
. 'Please choose another linked task.'
);
}
}
} catch (InvalidArgumentException $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorWrongArgs($exception->getMessage());
} catch (Exception $exception) {
$this->logger->error('Failed to process prospect', [
'prospect_data' => $prospectData,
'reason' => $exception->getMessage(),
]);
// Return a JSON response with the response array and status code.
return $this->response->errorInternalError(
'Sorry, an error occurred. Please try again or reach out to support if the problem continues.'
);
}
}
if ($categoryId) {
$category = PlaybookCategory::uuid($categoryId);
if ($category->playbook->team_id !== $team->id) {
throw new InvalidArgumentException('Sorry, this category does not belong to your playbook.');
}
$activity->playbook_category_id = $category->id;
}
$this->logger->info('Prospect data', [
'lead_id' => $lead?->getId(),
'account_id' => $account?->getId(),
'contact_id' => $contact?->getId(),
'opportunity_id' => $opportunity?->getId(),
'stage_id' => $stage?->getId(),
]);
if ($title) {
$activity->title = $title;
}
if ($summary) {
$activity->summary = $summary;
}
if ($crmProviderId) {
$activity->crm_provider_id = $crmProviderId;
}
if ($callStage) {
$this->logger->info('Setting stage id', ['stageId' => $callStage->id]);
$activity->stage_id = $callStage->id;
}
if ($lead) {
$this->logger->info('Setting lead id', ['leadId' => $lead->id]);
$activity->lead_id = $lead->id;
// If we are changed from an account > lead, unset the account data.
$this->logger->info('Unsetting account id, opportunity id, contact id, value');
$activity->account_id = null;
$activity->opportunity_id = null;
$activity->contact_id = null;
$activity->value = null;
}
if ($account) {
$this->logger->info('Setting account id', ['accountId' => $account->id]);
$activity->account_id = $account->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('unsetting lead id');
$activity->lead_id = null;
// Unset the contact if switching different accounts. Will be set up below if still applicable.
if (! $team->hasFeature(FeatureEnum::LINK_ACTIVITY_TO_MULTIPLE_PROSPECTS) || empty($contact)) {
$this->logger->info('Unsetting contact id');
$activity->contact_id = null;
}
}
if ($opportunity) {
$this->logger->info('setting opportunity id', ['opportunityId' => $opportunity->id]);
$this->logger->info('unsetting lead id');
$activity->opportunity_id = $opportunity->id;
$activity->value = $opportunity->value;
// If we are changed from an lead > account, unset the lead data.
$activity->lead_id = null;
}
if ($contact) {
$this->logger->info('setting contact id', ['contactId' => $contact->id]);
$activity->contact_id = $contact->id;
// If we are changed from an lead > account, unset the lead data.
$this->logger->info('Unsetting lead id');
$activity->lead_id = null;
}
$activity->is_internal = $isInternal;
$activity->save();
$activity->refresh();
$this->logger->notice('Activity saved', [
'activity_id' => $activity->getId(),
'lead_id' => $activity->lead_id,
'account_id' => $activity->account_id,
'contact_id' => $activity->contact_id,
'opportunity_id' => $activity->opportunity_id,
'stage_id' => $activity->stage_id,
'crm_provider_id' => $activity->getCrmProviderId(),
]);
// Store entities as field data on the activity.
$updatedData = $this->storeEntities($crmService, $activity, $layout, $rawEntities);
if ($activity->isLoggable()) {
// Follow-up Task or Event data.
$followupData = $this->fetchFollowupEntities($crmService, $layout, $rawEntities);
$this->logger->info('CRM LOG manual log triggered', [
'activityId' => $activity->getUuid(),
'followupData' => $followupData,
'userId' => $user->getUuid(),
]);
// Store data in the CRM.
// ++add check for crm_required
$job = new SaveActivity($activity, $followupData);
if ($updatedData) {
$job->delay(Carbon::now()->addMinutes($jobDelay));
}
dispatch($job);
// Manually dispatch log for Opportunity or Prospect added
if ($activity->hasOpportunity() || $activity->hasProspect()) {
event(new ActivityProspectAdded(
activity: $activity,
eventSource: 'manually-log-crm-data'
));
}
}
return $this->response->withOk();
}
/**
* Extract any activity data to be upserted in the Lead/Opportunity/Task etc in the CRM.
*
* @param ServiceInterface $service
* @param Activity $activity
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function storeEntities(ServiceInterface $service, Activity $activity, Layout $layout, array $entities): array
{
$updatedData = [];
$existingData = $activity->data()->get();
// We need to delete any existing data to overwrite with latest values.
$activity->data()->delete();
$layoutEntities = $layout->entities()
->with('field', 'parent')
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->get();
/** @var LayoutEntity $entity */
foreach ($layoutEntities as $entity) {
// If the user has provided a value for this entity
if (array_key_exists($entity->id_string, $entities)) {
$value = $entities[$entity->id_string];
// Convert raw data into values that the CRM can consume.
if ($value) {
$value = $service->normalizeValue($entity->field->type, $value);
}
// Check the field is part of the activity-summary section.
if ($entity->parent && $entity->parent->label === 'activity-summary' && $value) {
// This is the internal database ID, not the external CRM ID.
$objectId = null;
switch ($entity->field->object_type) {
case Field::OBJECT_ACCOUNT:
$objectId = $activity->account_id;
break;
case Field::OBJECT_CONTACT:
$objectId = $activity->contact_id;
break;
case Field::OBJECT_OPPORTUNITY:
$objectId = $activity->opportunity_id;
break;
case Field::OBJECT_LEAD:
$objectId = $activity->lead_id;
break;
case Field::OBJECT_TASK:
case Field::OBJECT_EVENT:
$objectId = $activity->id;
break;
}
if ($objectId) {
/** @var FieldData $data */
$data = $activity->data()->create([
'crm_layout_entity_id' => $entity->id,
'crm_field_id' => $entity->crm_field_id,
'object_type' => $entity->field->object_type,
'object_id' => $objectId,
'value' => $value,
]);
// Never send read-only field data to the CRM.
if ($entity->read_only === false && $entity->is_visible) {
$existingValue = $existingData
->where('crm_layout_entity_id', $entity->id)
->where('crm_field_id', $entity->crm_field_id)
->where('object_type', $entity->field->object_type)
->where('object_id', $objectId)
->first();
// If the field was actually changed, we need to reflect this in the CRM too.
if ($existingValue === null || $existingValue->value !== $value) {
$updatedData[] = $data->id;
}
}
}
}
}
}
return $updatedData;
}
/**
* Extract any followup data to be dispatched in a job to create a new Task/Event in the CRM.
*
* @param ServiceInterface $crmService
* @param Layout $layout
* @param array $entities The raw entity data from user
*
* @return array
*/
private function fetchFollowupEntities(ServiceInterface $crmService, Layout $layout, array $entities): array
{
$fieldData = [];
foreach ($entities as $entityId => $value) {
// Only bother with fields that have a value.
if ($value) {
// Extract the entity from the UUID. Check the field is valid and part of the follow-up section.
$entity = $layout->entities()
->uuid($entityId, false)
->whereHas('parent', function ($query) {
$query->where('label', 'follow-up');
})
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->first();
if ($entity) {
// Convert raw data into values that the CRM can consume.
$value = $crmService->normalizeValue($entity->field->type, $value);
// Add the field and value to the payload.
$fieldData += [
$entity->field->crm_provider_id => $value,
];
}
}
}
return $fieldData;
}
/**
* @param Activity $activity
*/
private function validateSummary(Activity $activity): void
{
$team = $activity->user->team;
$crmProvider = $team->crm->provider;
$attributes = [];
$rules = [
'layout_id' => 'required|uuid:crm_layouts,crm_configuration_id,' . $team->crm_id,
'title' => 'string|max:250',
'prospects' => 'required|array',
'opportunity_id' => new CrmReference($crmProvider),
'category_id' => 'uuid:playbook_categories|required_unless:is_internal,true',
'stage_id' => 'uuid:stages,team_id,' . $team->id, // Todo: move to proper validator
'summary' => 'max:50000',
'nId' => 'exists:notifications,id',
'crm_id' => new CrmReference($crmProvider),
'entities' => 'array',
'is_internal' => 'boolean',
];
/** @var Layout $layout */
$layout = $team->crm->layouts()->uuid($this->request->input('layout_id'));
// Only validate fields, not headers etc. If not loggable, we don't care about follow-up section.
$entities = $layout->entities()
->where('read_only', 0)
->whereHas('field', function ($query) {
$query->where('is_selectable', 1);
})
->whereHas('parent', function ($query) use ($activity) {
if ($activity->isLoggable() === false) {
$query->where('label', '<>', 'follow-up');
}
});
$isInternal = $this->request->input('is_internal', false);
foreach ($entities->get() as $entity) {
$rules += $this->buildFieldValidator($entity, $isInternal);
$attributes += $this->buildFieldMessage($entity);
}
$this->request->validate($rules, [], $attributes);
}
private function buildFieldValidator(LayoutEntity $entity, bool $isInternal): array
{
return [
'entities.' . $entity->id_string => $entity->getValidator($isInternal),
];
}
/**
* @param LayoutEntity $entity
*
* @return array
*/
private function buildFieldMessage(LayoutEntity $entity): array
{
$label = $entity->label;
if ($label === null) {
$label = $entity->field->label;
}
return [
'entities.' . $entity->id_string => $label,
];
}
public function search(Request $request, ElasticActivityRepository $repository): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->debugLog(
$user,
'User extracted from request',
['user' => $user->getId(), 'tz' => $user->getTimezone()]
);
$searchCriteria = Criteria::createFromRequest($request->all(), $user->getTimezone());
$this->debugLog(
$user,
'ActivitySearch criteria built',
['searchCriteria' => $searchCriteria]
);
$filterSet = $this->activitySearch->getHomepageFilterSet($searchCriteria, $user);
$this->debugLog($user, 'FilterSet built', ['filterSet' => $filterSet]);
$this->validateSearch($request, $filterSet);
$this->debugLog($user, 'Request validated');
$searchResponse = $repository->onDemandSearch($user, $searchCriteria, $filterSet);
/** @var Collection<Activity> $activities */
$activities = $searchResponse['results'];
$this->debugLog($user, 'Activities ES response extracted');
$hideInternalMeetingsSetting = $this->teamRepository->getTeamSettingByTeamId(
$user->getTeamId(),
TeamSetting::HIDE_INTERNAL_SCHEDULED_MEETINGS->name(),
);
if ($hideInternalMeetingsSetting?->getValue() === '1') {
$activities = $activities->filter(function (Activity $activity) {
if ($activity->is_internal && empty($activity->actual_start_time)) {
return false;
}
return true;
});
}
$this->debugLog($user, 'Internal meetings (?!) filtered');
$this->response->getManager()
->parseIncludes([
'category',
'organizer.group',
'prospect',
'stage',
'opportunity',
'stats',
'scorecards',
'masterTrack',
'activeParticipants',
'notification',
])
->setSerializer(new JsonSerializer());
$transformerExcludes = $this->request->input('exclude');
if ($transformerExcludes) {
$this->response->getManager()->parseExcludes($transformerExcludes);
}
$this->debugLog($user, 'Response Manager (?!) applied');
$transformer = new ActivityTransformer();
$transformer->setConsumer($user);
$this->debugLog($user, 'Activity Transformer added');
$resource = new \League\Fractal\Resource\Collection($activities, $transformer);
$page = $searchCriteria->getPageNumber();
$this->debugLog($user, 'Search criteria page number called', ['page' => $page]);
$histogram = array_pluck(array_get($searchResponse, 'histogram.buckets', []), 'doc_count', 'key_as_string');
$this->debugLog($user, 'Histogram generated. Response is ready.', ['histogram' => $histogram]);
return $this->response->withArray([
'pagination' => [
'total' => $searchResponse['totalHits'],
'current' => $page,
'prev' => max($page - 1, 1),
'next' => $page + 1,
],
'results' => $this->response->getManager()->createData($resource)->toArray(),
'histogram' => $histogram,
]);
}
private function debugLog(User $user, string $logMessage, ?array $context = []): void
{
// Debug for Learning People Only
if ($user->getTeamId() !== 260) {
return;
}
Log::notice(
sprintf('[activity-search-controller] %s', $logMessage),
$context
);
}
/** @throws ValidationException */
private function validateSearch(Request $request, FilterDefinitionCollection $filterSet, ?string $prefix = null): void
{
$rules = [
'exclude' => 'array',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
];
if ($prefix !== null && mb_strpos($prefix, '.') !== false) {
$rules[rtrim($prefix, '.')] = sprintf(
'required|array|max:%d',
$filterSet->count()
);
}
$validationRules = $filterSet->getValidationRules($prefix)
->merge($rules)
->all();
$request->validate($validationRules);
}
public function createActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$search = $this->updateOrCreateActivitySearch($request);
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function updateActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('update', $search);
$this->updateOrCreateActivitySearch($request, $search);
return $this->response->withOk();
}
private function storeNamedSearchFilters(
Collection $request,
Search $search,
FilterDefinitionCollection $filterSet,
?string $prefix = null,
): self {
$arrayTypeProperties = $filterSet
->getPropertyTypes([
FilterDefinitionCollection::PROPERTY_TYPE_ARRAY,
])
->all();
$supportedRequestProperties = $filterSet->getSupportedRequestProperties($prefix);
foreach ($supportedRequestProperties as $requestPropertyName) {
if (! array_has($request, $requestPropertyName)) {
continue;
}
/** @var string|string[] $propertyValue */
$propertyValue = array_get($request, $requestPropertyName);
$propertyName = $prefix === null
? $requestPropertyName
: mb_substr($requestPropertyName, mb_strlen($prefix));
$isArrayType = array_has($arrayTypeProperties, $propertyName);
if (! $isArrayType) {
/** @var string $requestPropertyValue */
$search->filters()->updateOrCreate(
[
'filter' => $propertyName,
],
[
'value' => $propertyValue,
]
);
continue;
}
/** @var string[] $requestPropertyValue */
/** @var SearchFilter[]|Collection $existingFilterValues */
$existingFilterValuesKeyed = $search->filters()
->where('filter', $propertyName)
->get()
->keyBy('id');
// Iterate over values provided as request parameters
foreach ($propertyValue as $value) {
/** @var SearchFilter|null $valueFilter */
$valueFilter = $search->filters()
->where(
[
'filter' => $propertyName,
'value' => $value,
]
)
->first();
if ($valueFilter !== null) {
// Remove filter value pair from list to be deleted
$existingFilterValuesKeyed->forget($valueFilter->id);
} else {
// Add new filter/value pair
$search->filters()->updateOrCreate([
'filter' => $propertyName,
'value' => $value,
]);
}
}
// Delete filter value pairs for this filter that no longer exist in request parameters
foreach ($existingFilterValuesKeyed as $existingFilter) {
$existingFilter->delete();
}
}
/** @var Collection<int, SearchFilter> $filtersKeyed */
$filtersKeyed = $search->filters()->get()->keyBy('filter');
// wipe removed filters from this search
foreach ($filtersKeyed as $filterName => $filter) {
if (array_has($request, $prefix . $filterName)) {
continue;
}
// Remove all filter values for this filter
$search->filters()->where('filter', $filterName)->delete();
}
return $this;
}
/**
* @throws AuthorizationException
*/
public function fetchActivitySearch(
Search $search,
Request $request,
SearchTransformer $searchTransformer,
): JsonResponse {
$this->authorize('view', $search);
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withItem(
$search,
$searchTransformer
->withConsumer($user)
);
}
public function listActivitySearch(Request $request, SearchTransformer $searchTransformer): JsonResponse
{
/** @var User $user */
$user = $request->user();
$this->response
->getManager()
->setSerializer(new JsonSerializer());
return $this->response->withCollection(
$user->searches()->get(),
$searchTransformer
->withConsumer($user)
);
}
/**
* Deletes a saved search
*
* @param Request $request
* @param Search $search
*
* @throws Exception
*
* @return JsonResponse
*/
public function deleteActivitySearch(Request $request, Search $search): JsonResponse
{
$this->authorize('delete', $search);
// Orphan any AutomatedReports that use this search
$search->automatedReports()->withTrashed()->update(['activity_search_id' => null]);
// Delete filters and the search itself
$search->filters()->delete();
$search->delete();
return $this->response->withOk();
}
public function live(Request $request, ElasticActivityRepository $repository): JsonResponse
{
$user = $this->getUserFromRequest($request);
$this->request->validate([
'sort_direction' => 'in:asc,desc',
'limit' => 'integer|min:1|max:50',
'page' => 'integer|min:1',
]);
$activities = $repository->getLiveCoachingEligibleActivities(
user: $user,
lookBackMinutes: self::LOOK_BACK,
limit: (int) $this->request->input('limit', 25),
page: (int) $this->request->input('page', 1),
sortBy: ['actual_start_time', 'scheduled_start_time'],
sortDirection: (string) $this->request->input('sort_direction', 'asc'),
);
$this->response
->getManager()
->parseIncludes(['organizer.group', 'prospect'])
->setSerializer(new JsonSerializer());
return $this->response->withCollection($activities, new ActivityTransformer());
}
/**
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function show(Activity $activity, ActivityService $activityService): JsonResponse
{
$this->authorize('show', $activity);
$user = $activity->getUser();
$team = $user->getTeam();
// Sync the opportunity with the latest data if possible.
if ($activity->opportunity_id) {
try {
$crmService = $this->providerRegistry->get($team->crm->provider);
if (! $user->isCrmRequired()) {
$crmService->setUser($team->getOwner());
} else {
$crmService->setUser($user);
}
$crmService->syncOpportunity($activity->opportunity->crm_provider_id);
} catch (Exception $exception) {
// Move on.
}
}
$activityData = $activityService->getActivityData($this->request->user(), $activity);
return response()->json($activityData);
}
public function createRecording(Activity $activity)
{
$this->authorize('record', $activity);
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Tell Twilio to start recording this activity.
if ($activity->recording_state === Activity::RECORDING_OFF) {
$job = (new StartRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withCreated();
}
return $this->response->errorGone('Activity is already recording.');
}
public function updateRecording(Request $request, Activity $activity)
{
$this->authorize('record', $activity);
$request->validate([
'preference' => 'boolean',
'state' => [
'string',
Rule::in([
Activity::RECORDING_IN_PROGRESS,
Activity::RECORDING_PAUSED,
]),
],
]);
if ($request->has('state')) {
if ($activity->hasRecordingReasonComplianceRestricted()) {
return $this->response->errorGone('Recording this number has been disabled by your organization.');
}
// Toggle the recording state between paused and resumed.
if (! $activity->isRecordingState(Activity::RECORDING_OFF)) {
$job = (new ToggleRecording($activity, $request->input('state')))
->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Recording is not toggleable.');
}
if ($request->has('preference')) {
$activity->update([
'recording_preference' => $request->input('preference') ? 1 : 0,
]);
return $this->response->withOk();
}
return $this->response->errorWrongArgs('Something went wrong');
}
public function stopRecording(Activity $activity)
{
$this->authorize('stopRecord', $activity);
// Tell Twilio to stop recording this activity.
if ($activity->isRecordingState(Activity::RECORDING_IN_PROGRESS)) {
$job = (new StopRecording($activity))->onQueue(Constants::QUEUE_CONFERENCES);
dispatch($job);
return $this->response->withOk();
}
return $this->response->errorGone('Activity is not recording.');
}
/**
* Add activity to this user's favorites playlist
*
* @throws AuthorizationException
*/
public function favorite(Activity $activity, PlaylistActivityRepository $playlistActivityRepository): JsonResponse
{
$this->authorize('favorite', $activity);
$user = $this->getUserFromRequest($this->request);
$favorite = $activity->wasFavoritedBy($user);
$name = $activity->activity_title ?? '';
// It needs to check at least one record.
if (! $favorite) {
$favoritePlaylist = $user->favoritePlaylist();
$playlistActivity = $playlistActivityRepository->findByBaseActivityUserAndPlaylist(
$activity,
$user,
$favoritePlaylist
);
if ($playlistActivity !== null) {
$playlistActivity->update(
// Just update, don't sort.
['start_time' => 0, 'name' => mb_strimwidth($name, 0, 100)],
);
} else {
$playlistActivity = $activity->playlistActivities()->create([
'playlist_id' => $favoritePlaylist->getId(),
'user_id' => $user->getId(),
'start_time' => 0,
'name' => mb_strimwidth($name, 0, 100),
]);
// Sort it on top.
$playlistActivity->update(
[
'sort' => $playlistActivityRepository->calculateNewSortOrder(
null,
$playlistActivity,
),
],
);
}
$playlistActivityRepository->calculateNewSortOrder(null, $playlistActivity);
return new JsonResponse([], JsonResponse::HTTP_CREATED);
}
return new JsonResponse(
[
'error' => [
'code' => AbstractResponse::CODE_CONFLICT,
'http_code' => JsonResponse::HTTP_CONFLICT,
'message' => 'Resource Already Exists',
],
],
JsonResponse::HTTP_CONFLICT,
);
}
/**
* Remove activity from this user's favorites playlist
*
* @param Activity $activity
*
* @throws AuthorizationException
*
* @return mixed
*/
public function unfavorite(Activity $activity)
{
$user = $this->request->user();
$favorit...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49734
|
1769
|
10
|
2026-05-18T06:55:24.958715+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087324958_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comà Daily - Platform - 10 m left100% C8• Mon 18 May 9:55:24Nikolay Yankov (Presenting)Fietaitinbe@ For you© Recent|# Starred8? Apps07 Spacesaurcoy) Service-Desk|® Summary@ Queues1@ Piatform team3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& CustomersQ ChannelsE Email logsDevetoper escaiat.i: Slack integration§ Reporting CenterE Archived work itemsJiminny (Oid)Jiminny (New)(7 Ser(7 ISROTabE3 3mE3 ProDAD X BUO X (St x ®a x8 cia. xCo X*0.G0Jm x Quc x3 Pp xhttps://iminny.atlassian.net/jra/servicedesk/projects/SRDJaueues/custom/37/SRD-6859- JmanProjects15 S5• Home | Salestorce08 0 © 1CОсеслоSeroy 8xSearch+ Create< Baсk30 5R0-66591LATUS Group - Exec Summary Inaccuracyd Link work item* Add form+ Escalate work itemB Add designCreateGabriela Dureva raised this request via JiraDescriptionHi team,Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a part.of this conversation so the call shouldnt be the scope of her summary. E Coaching Proffies - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate adoed +image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoachlng Proflies - Apr 2026 - Strategic Account Managers, pdf72 KB15 May 2026, 12:18 pm0 cal• DevAsk RovoAnalyzing~DetailsAssignee31 Stellyan GeorgievAssign to meReporter@ Gabriela DurevaRequest TypeNoneKnowledge base View related.Type of InfoSec incidentNonePriority level &P2 MediumComponents(InfoSec)ComponentsNoneExpected ouscomenaActual outcomeNaMon 18 May 9:56AJ BockmarksSteliyan GeorgievNikolay YankovNikolay lvanovCHF 6CAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik8:59Lộ3...
|
NULL
|
2949895352762543399
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comà Daily - Platform - 10 m left100% C8• Mon 18 May 9:55:24Nikolay Yankov (Presenting)Fietaitinbe@ For you© Recent|# Starred8? Apps07 Spacesaurcoy) Service-Desk|® Summary@ Queues1@ Piatform team3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& CustomersQ ChannelsE Email logsDevetoper escaiat.i: Slack integration§ Reporting CenterE Archived work itemsJiminny (Oid)Jiminny (New)(7 Ser(7 ISROTabE3 3mE3 ProDAD X BUO X (St x ®a x8 cia. xCo X*0.G0Jm x Quc x3 Pp xhttps://iminny.atlassian.net/jra/servicedesk/projects/SRDJaueues/custom/37/SRD-6859- JmanProjects15 S5• Home | Salestorce08 0 © 1CОсеслоSeroy 8xSearch+ Create< Baсk30 5R0-66591LATUS Group - Exec Summary Inaccuracyd Link work item* Add form+ Escalate work itemB Add designCreateGabriela Dureva raised this request via JiraDescriptionHi team,Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a part.of this conversation so the call shouldnt be the scope of her summary. E Coaching Proffies - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDate adoed +image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoachlng Proflies - Apr 2026 - Strategic Account Managers, pdf72 KB15 May 2026, 12:18 pm0 cal• DevAsk RovoAnalyzing~DetailsAssignee31 Stellyan GeorgievAssign to meReporter@ Gabriela DurevaRequest TypeNoneKnowledge base View related.Type of InfoSec incidentNonePriority level &P2 MediumComponents(InfoSec)ComponentsNoneExpected ouscomenaActual outcomeNaMon 18 May 9:56AJ BockmarksSteliyan GeorgievNikolay YankovNikolay lvanovCHF 6CAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik8:59Lộ3...
|
49733
|
NULL
|
NULL
|
NULL
|
|
49735
|
1770
|
4
|
2026-05-18T06:55:25.298046+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087325298_m2.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
iilPhostormVIewINavicareCodeLaravelKeractorFV faVs iilPhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect©ActivityController.php© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcache.pnp© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.php(C) LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohoC) RequestGenerateReport.Job.ohv>D Livestream(C) AutomatedReportkesult.onp(C) AutomatedReport.phpMallboxes• Midratefinal class ActivityController extends Controller implements CommenPlavbackithemes1090public function listActivitySearch(Request $request, SearchTransformer SsealM PlavbooksPlaylists> M Postmark/** @var User Suser *Suser = $request->userO:> M PronhetAv M Renorts1095Sthis->response->getManagerO© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 1097© AutomatedReportsSendCommand.pht 1098© CreateMockAskJiminnyReportResultC 1099© DeleteReportCommand.php1106© GenerateMarketingReport.php© Team.php1102© Usage.php>07 Slack11194-›serserauzertnew Jsonserzalzzer00:return Sthis->response->withCollectiondsuser->searcheso->geto->withconsumer(Suser)›_ TeamsLocal ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04.26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23l1row retrieved ctartina from 1 in 740 mc (eyecution: 186 mc fetchina- 554 mcl=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:use Pipedrive versions v2 Apii ActivitiecAni.use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:= 22Dclass TestPipedrive0fficialSdkCommand extends CommandAccept Reject24 otprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.266IIII6 usagesprivate acray edigsylt Accept File g- X Reject File t*a+ 2of2 files →Nothina to show#Daily - Platform • 10 m left100% Lz. Mon 18 May 9:55:25AskJiminnyReportActivityServiceTest v+0..Debugging PipedriveTnoughts03 tasks done•Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallableTest v2 APl endpoints with official SDKSearched v2 in vendor/pipedrive (2)Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts >Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiTestPipedriveOfficialSdkCommand.phpThoughts >• TestPipedriveOfficialSdkCommand.php=• TestPipedriveOfficialSdkCommand.php2 fles 450-26>Ask anvthina (*4L)+ &codeSWE-1.6we should use v2 with new SDK. Are you using new SDK?+ 205 tokens+16 -8+ 238 tokens2) Reject allAccept allW Windsurf Teams 14:1 (35 chars, 1 line break) UTF-8 ia 4 spaces...
|
NULL
|
-7013476715140390029
|
NULL
|
idle
|
ocr
|
NULL
|
iilPhostormVIewINavicareCodeLaravelKeractorFV faVs iilPhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect©ActivityController.php© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcache.pnp© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.php(C) LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohoC) RequestGenerateReport.Job.ohv>D Livestream(C) AutomatedReportkesult.onp(C) AutomatedReport.phpMallboxes• Midratefinal class ActivityController extends Controller implements CommenPlavbackithemes1090public function listActivitySearch(Request $request, SearchTransformer SsealM PlavbooksPlaylists> M Postmark/** @var User Suser *Suser = $request->userO:> M PronhetAv M Renorts1095Sthis->response->getManagerO© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 1097© AutomatedReportsSendCommand.pht 1098© CreateMockAskJiminnyReportResultC 1099© DeleteReportCommand.php1106© GenerateMarketingReport.php© Team.php1102© Usage.php>07 Slack11194-›serserauzertnew Jsonserzalzzer00:return Sthis->response->withCollectiondsuser->searcheso->geto->withconsumer(Suser)›_ TeamsLocal ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04.26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23l1row retrieved ctartina from 1 in 740 mc (eyecution: 186 mc fetchina- 554 mcl=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipearive versions vi Ap1 Personrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:use Pipedrive versions v2 Apii ActivitiecAni.use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:= 22Dclass TestPipedrive0fficialSdkCommand extends CommandAccept Reject24 otprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.266IIII6 usagesprivate acray edigsylt Accept File g- X Reject File t*a+ 2of2 files →Nothina to show#Daily - Platform • 10 m left100% Lz. Mon 18 May 9:55:25AskJiminnyReportActivityServiceTest v+0..Debugging PipedriveTnoughts03 tasks done•Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallableTest v2 APl endpoints with official SDKSearched v2 in vendor/pipedrive (2)Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts >Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiTestPipedriveOfficialSdkCommand.phpThoughts >• TestPipedriveOfficialSdkCommand.php=• TestPipedriveOfficialSdkCommand.php2 fles 450-26>Ask anvthina (*4L)+ &codeSWE-1.6we should use v2 with new SDK. Are you using new SDK?+ 205 tokens+16 -8+ 238 tokens2) Reject allAccept allW Windsurf Teams 14:1 (35 chars, 1 line break) UTF-8 ia 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49736
|
1769
|
11
|
2026-05-18T06:55:27.995020+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087327995_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)à Daily - Platform - 10 m left100% C8• Mon 18 May 9:55:2700••FleTát® For you© Recent|# Starred8? Apps0 SpacesaurcoService-Desk|® Summary@ QueuesbleaeuI@ Piatform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& CustomersQ ChanneisE Email logs%› Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Jiminny (New)SerC7 (SRDTab83 3mlE3 ProM( Alte x E3 мO xSche X o Cun x* Ca X•Cost X"04Q00 Jm: x Q MCePipe xhttps://fjminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859- JiyProjects• Home | Salestorce08E 0© % Case сrоко!SentryL tasкSearch+ Create< Back30 3К0-66591LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item Add designCreate vGabriela Dureva raised this request via JiraDescriptionHi team,Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this conversation so the call shouldnt be the scope of her summary. E Coaching Proffies - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeAttachments 2SizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Apr 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmO ca0 DewAsk RovoAnalyzingDetailsAssignee31 Stellyan GeorgievAssign to meReporter6 Gabriela DurevaRequest TypeNoneKnowledge base View relsted.Type of InfoSec incidentNonePriority level &P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomenaActual outcomen/a8• Mon 18 May 9:55Steliyan GeorgievNikolay YankovNikolay lIvanovAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:02Lộ3...
|
NULL
|
-8021266755566334504
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)à Daily - Platform - 10 m left100% C8• Mon 18 May 9:55:2700••FleTát® For you© Recent|# Starred8? Apps0 SpacesaurcoService-Desk|® Summary@ QueuesbleaeuI@ Piatform team> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& CustomersQ ChanneisE Email logs%› Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Jiminny (New)SerC7 (SRDTab83 3mlE3 ProM( Alte x E3 мO xSche X o Cun x* Ca X•Cost X"04Q00 Jm: x Q MCePipe xhttps://fjminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859- JiyProjects• Home | Salestorce08E 0© % Case сrоко!SentryL tasкSearch+ Create< Back30 3К0-66591LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work item Add designCreate vGabriela Dureva raised this request via JiraDescriptionHi team,Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this conversation so the call shouldnt be the scope of her summary. E Coaching Proffies - Apr 2026 - Strategic Account Managers, pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeAttachments 2SizeDate added+image-20260515-114153.png1.2 MB 15 May 2026, 12:42 pmCoaching Profiies - Apr 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmO ca0 DewAsk RovoAnalyzingDetailsAssignee31 Stellyan GeorgievAssign to meReporter6 Gabriela DurevaRequest TypeNoneKnowledge base View relsted.Type of InfoSec incidentNonePriority level &P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomenaActual outcomen/a8• Mon 18 May 9:55Steliyan GeorgievNikolay YankovNikolay lIvanovAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:02Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49737
|
1769
|
12
|
2026-05-18T06:55:33.062357+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087333062_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)à Daily - Platform - 10 m left100% C8• Mon 18 May 9:55:3257|-18FleTớt® For you© Recent|# Starred8? Apps02 Spacesaaarco5 Service-Desk|@ Summary@ QueuesplerleuI@ Platform team 3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• ChanneislE Emall logs% Developer escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)RecentJiminny (New)yServC7 (SRDTab83 JmlE3 Pron•Atte Xx Mo x(a Sche x© Cur x• сa XCost XUumx@MolPipe x8 JmO cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859- JeeC Projects• Home | Salestorce* ClaudeO CircieciA Sentry*xIL tasкinsights & Coachin…C DevSearch+ Create< Back3 3К0-66591LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemg Add designCreate vGabriela Dureva raised this request via JiraDescriptionHi team,Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this corversation so the call shouldn't be the scope of her summary. E Coaching Profies - Apr 2026 - Strategic Account Managers,pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDute adsed+image-20260515-114153.png1.2 MB15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmAsk RovoAharyzingDetailsAssignee3 Stelyan GeorgievAssign to meReporter€ Gabriela DurevaRequest TypeNoneKnowledge base View related….Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aMon 18 May 9:56Steliyan GeorgievNikolay YankovNikolay IvanovPREMIUMAneliya AngelovaLukas Kovalik9:07Lộ39:55 AM | Daily - Platform...
|
NULL
|
3439946808471856410
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)à Daily - Platform - 10 m left100% C8• Mon 18 May 9:55:3257|-18FleTớt® For you© Recent|# Starred8? Apps02 Spacesaaarco5 Service-Desk|@ Summary@ QueuesplerleuI@ Platform team 3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base& Customers• ChanneislE Emall logs% Developer escalati.if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)RecentJiminny (New)yServC7 (SRDTab83 JmlE3 Pron•Atte Xx Mo x(a Sche x© Cur x• сa XCost XUumx@MolPipe x8 JmO cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859- JeeC Projects• Home | Salestorce* ClaudeO CircieciA Sentry*xIL tasкinsights & Coachin…C DevSearch+ Create< Back3 3К0-66591LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemg Add designCreate vGabriela Dureva raised this request via JiraDescriptionHi team,Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a partof this corversation so the call shouldn't be the scope of her summary. E Coaching Profies - Apr 2026 - Strategic Account Managers,pat|Could you prease check?Steps to reproducen/aImpactNoneRoot causeSizeDute adsed+image-20260515-114153.png1.2 MB15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmAsk RovoAharyzingDetailsAssignee3 Stelyan GeorgievAssign to meReporter€ Gabriela DurevaRequest TypeNoneKnowledge base View related….Type of InfoSec IncidentNonePriority level#P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aMon 18 May 9:56Steliyan GeorgievNikolay YankovNikolay IvanovPREMIUMAneliya AngelovaLukas Kovalik9:07Lộ39:55 AM | Daily - Platform...
|
49736
|
NULL
|
NULL
|
NULL
|
|
49738
|
1769
|
13
|
2026-05-18T06:55:36.069803+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087336069_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)à Daily - Platform - 10 m left100% C28•Mon 18 May 9:55:35006FleTớt® For you© Recent|# Starred8? Apps02 Spacesacarco5 Service-Desk|@ Summary@ QueuesF-18plenleuI@ Platform team 3> Team Priority= View all que... >Service requestsA Incidentsll Reports@ Knowledge Base& Customers• Channeisl8 Emall logs% Developer escalati.f: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)RecentJiminny (New)9:55 AM | Daily - PlatformLộ3yServN7 (SRDTab83 3mi4000E3 PronC Alte x | 83 мо x(a Sche xolCurs xI* 0a xCost X0um x@MoPipe x© JmO cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859C Projects• Home | Salesforce* ClaudeO CircieciSentry*xIL tasкInsights & CoachinSearch+ Create< Back30 3К0-68501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreate vGabriela Dureva raised this request via JiraDescriptionHi team,Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a part |of this conversation so the call shouldn't be the scope of her summary. E Coaching Profies - Apr 2026 - Strategic Account Managers, pat|Couid you prease check?Steps to reproducen/aImpactNoneRoot causeAttachments 2SizeDate adsed+image-20260515-114153.png1.2 MB15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmC DevAsk RovoAharyzingyDetailsAssignee3 Steliyan GeorgievAssign to meReporter€ Gabrieta DurevaRequest TypeNoneKnowledge base View related….Type of InfoSec IncidentNonePriority level #P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aMon 18 May 9:56Steliyan GeorgievNikolay YankovNikolay wanovPREMIUMAПЕ GОLAneliya AngelovaLukas Kovalik9:10...
|
NULL
|
8003621012373614793
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelp> 0meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)à Daily - Platform - 10 m left100% C28•Mon 18 May 9:55:35006FleTớt® For you© Recent|# Starred8? Apps02 Spacesacarco5 Service-Desk|@ Summary@ QueuesF-18plenleuI@ Platform team 3> Team Priority= View all que... >Service requestsA Incidentsll Reports@ Knowledge Base& Customers• Channeisl8 Emall logs% Developer escalati.f: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)RecentJiminny (New)9:55 AM | Daily - PlatformLộ3yServN7 (SRDTab83 3mi4000E3 PronC Alte x | 83 мо x(a Sche xolCurs xI* 0a xCost X0um x@MoPipe x© JmO cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6859C Projects• Home | Salesforce* ClaudeO CircieciSentry*xIL tasкInsights & CoachinSearch+ Create< Back30 3К0-68501LATUS Group - Exec Summary InaccuracyLink work item* Add form+ Escalate work itemAdd designCreate vGabriela Dureva raised this request via JiraDescriptionHi team,Latus Group flagged the attached coaching profiles report, where on page 9, in Rebecca's coaching session it is referencing to a call with Dyson. Rebecca was not a part |of this conversation so the call shouldn't be the scope of her summary. E Coaching Profies - Apr 2026 - Strategic Account Managers, pat|Couid you prease check?Steps to reproducen/aImpactNoneRoot causeAttachments 2SizeDate adsed+image-20260515-114153.png1.2 MB15 May 2026, 12:42 pmCoaching Profiies - Ape 2026 - Strategic Account Managers,pat72 KB15 May 2026, 12:18 pmC DevAsk RovoAharyzingyDetailsAssignee3 Steliyan GeorgievAssign to meReporter€ Gabrieta DurevaRequest TypeNoneKnowledge base View related….Type of InfoSec IncidentNonePriority level #P2 MediumComponents(InfoSec)ComponentsNoneExpected outcomeActual outcomen/aMon 18 May 9:56Steliyan GeorgievNikolay YankovNikolay wanovPREMIUMAПЕ GОLAneliya AngelovaLukas Kovalik9:10...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49739
|
1769
|
14
|
2026-05-18T06:55:39.094783+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087339094_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)= Daily - Platform • 10 m left100% L28•Mon 18 May 9:55:38006+FleEditM Inbe57 ServProfiesF7 ISRD xTab83 ămiE3 Pron*Atte: Xz Mo|(a Sche xo curs x* Cia xCosthttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37C SmienyC Projects23 SSH• Home | SalesforceФ0 8I l Datadog O * Caudeecrоke!a SentryO JIMINNYSearch® For you© Recent|# Starred8. Apps02 Spacesacarco(9 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamQ Search work |Request typeStatusAssigneeMore fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterLalus droup - txec summaryP2 MediumGabriela DurevaplenleuI@ Platform team [3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base9 Customers ISRD-6853Moxso - Potential deal stagesP2 MediumLwotwurabugSRD-6343Sidekick SMS issueP2 Medium|Stoyan Tomos• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)RecentJiminny (Ne... + ..40200PipeL tasкLa insights & CoachinC Dev+ Create1a QO caAsk RovoMon 18 May 9:56Steliyan GeorgievNikolay YankovAssigneeil Stelyan Georgiev@ lukas Kovalk@ Lukas KovalkStatusANALYZINGKiAoToKeToavTriageCreated +13/May/2613/May/26Nikolay IvanovPRIMEENEAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:13Lộ3...
|
NULL
|
-2941935409145003030
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)= Daily - Platform • 10 m left100% L28•Mon 18 May 9:55:38006+FleEditM Inbe57 ServProfiesF7 ISRD xTab83 ămiE3 Pron*Atte: Xz Mo|(a Sche xo curs x* Cia xCosthttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37C SmienyC Projects23 SSH• Home | SalesforceФ0 8I l Datadog O * Caudeecrоke!a SentryO JIMINNYSearch® For you© Recent|# Starred8. Apps02 Spacesacarco(9 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamQ Search work |Request typeStatusAssigneeMore fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterLalus droup - txec summaryP2 MediumGabriela DurevaplenleuI@ Platform team [3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base9 Customers ISRD-6853Moxso - Potential deal stagesP2 MediumLwotwurabugSRD-6343Sidekick SMS issueP2 Medium|Stoyan Tomos• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)RecentJiminny (Ne... + ..40200PipeL tasкLa insights & CoachinC Dev+ Create1a QO caAsk RovoMon 18 May 9:56Steliyan GeorgievNikolay YankovAssigneeil Stelyan Georgiev@ lukas Kovalk@ Lukas KovalkStatusANALYZINGKiAoToKeToavTriageCreated +13/May/2613/May/26Nikolay IvanovPRIMEENEAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:13Lộ3...
|
49738
|
NULL
|
NULL
|
NULL
|
|
49740
|
1769
|
15
|
2026-05-18T06:55:42.094419+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087342094_m1.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesTools|W FirefoxFileEditViewHistoryBookmarksProfilesTools|WindowHelpDaily - Platform • 10 m left100% L2%•Mon 18 May 9:55:41meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FFleEdit7 ServProfiesF7 (SRD xTab83 ămiE3 Proe*Atter XE3 мСIhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37L JenyC Projects23 SSH• Home | SalesforceФ0 8O JMINNYSearch® For you© Recent|# Starred8? Apps02 Spacesacarco59 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamRequest typeStatusAssignee3 work itemsKeySummaryplelleuI@ Platform team [3> Team Priority= View all que... >• Service requestsA Incidentslal Reports@ Knowledge Base9 Customers IInaccuracySRD-6853Moxso - Potential deal stagesSRD-6343Sidekick SMS issue• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)RecentJiminny (Ne... + ..(a Sche x© cuns x* Cia xCost4000Q мCя3 PipeJim1a QO caEl Datadog $ Clauseecrоke!a Sentry*xIL tasкLa Insights & CoachinC Dev+ CreateAsk RovoMon 18 May 9:56Steliyan GeorgievNikolay YankovMore fiters ~Priority levelP2 MediumP2 MediumP2 Medium|Severity levelReporterGabriela DurevaStoyan TomosAssigneei Steliyan Georgiev@ lukas Kovalk© Lukas KovalkStatusANALYZINGKiAoToKeoiavTriageCreated +15/May/2613/May/2613/May/26Nikolay IvanovAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:16111...
|
NULL
|
420503956504703496
|
NULL
|
visual_change
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesTools|W FirefoxFileEditViewHistoryBookmarksProfilesTools|WindowHelpDaily - Platform • 10 m left100% L2%•Mon 18 May 9:55:41meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FFleEdit7 ServProfiesF7 (SRD xTab83 ămiE3 Proe*Atter XE3 мСIhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37L JenyC Projects23 SSH• Home | SalesforceФ0 8O JMINNYSearch® For you© Recent|# Starred8? Apps02 Spacesacarco59 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamRequest typeStatusAssignee3 work itemsKeySummaryplelleuI@ Platform team [3> Team Priority= View all que... >• Service requestsA Incidentslal Reports@ Knowledge Base9 Customers IInaccuracySRD-6853Moxso - Potential deal stagesSRD-6343Sidekick SMS issue• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)RecentJiminny (Ne... + ..(a Sche x© cuns x* Cia xCost4000Q мCя3 PipeJim1a QO caEl Datadog $ Clauseecrоke!a Sentry*xIL tasкLa Insights & CoachinC Dev+ CreateAsk RovoMon 18 May 9:56Steliyan GeorgievNikolay YankovMore fiters ~Priority levelP2 MediumP2 MediumP2 Medium|Severity levelReporterGabriela DurevaStoyan TomosAssigneei Steliyan Georgiev@ lukas Kovalk© Lukas KovalkStatusANALYZINGKiAoToKeoiavTriageCreated +15/May/2613/May/2613/May/26Nikolay IvanovAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:16111...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49741
|
1770
|
5
|
2026-05-18T06:55:42.651546+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087342651_m2.jpg...
|
PhpStorm
|
faVsco.js – TestPipedriveOfficialSdkCommand.php
|
1
|
NULL
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
PhostormVIewINavicareCodeLaravelKeractorFV faVsco. PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect©ActivityController.php© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcache.pnp© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.php(C) LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd(C)AutomatedReportsRenositorv.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohoC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesult.onp© AutomatedReport.phpMallboxes• Midratefinal class ActivityController extends Controller implements Commer sAAVPlavbackithemes1090public function listActivitySearch(Request $request, SearchTransformer SsealM PlavbooksPlaylists> M Postmark1093/** @var User Suser *Suser = $request->user0:> M PronhetAv M Renorts1095Sthis->response->getManagerO© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 1097© AutomatedReportsSendCommand.pht 1098© CreateMockAskJiminnyReportResultC 1099© DeleteReportCommand.php1106© GenerateMarketingReport.php© Team.php1102© Usage.php>07 Slack11194-›serserauzertnew Jsonserzalzzer00:return Sthis->response->withCollectiondsuser->searcheso->geto->withconsumer(Suser)›_ TeamsLocal ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost readv one call to he tocted & filac 8 05 26 14•54) hubsnot rate limit temn checkout 17 filoc 8 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04.26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22> Don't send if no s3 path (fix update to failed) 1 file, 17.04.26, 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40• web.oho fix router 1 file. 1.04.26. 9.23Code will hoin INF to underctand vour Laravel ann code II Generate |I Don't Show Anvmore (21 minutes aao)=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vI Ap1 Fersonrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:= 22Dclass TestPipedrive0fficialSdkCommand extends CommandAccept Reject24 ot25266IIIIprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':6 usagesprivate acray edigsylt Accept File g- X Reject File t*a+ 20f2 files →Nothina to show#Daily - Platform • 10 m left100% Lz• Mon 18 May 9:55:42AskJiminnyReportActivityServiceTest v+0..Debugging PipedriveTnoughts03 tasks done•Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallableTest v2 APl endpoints with official SDKSearched v2 in vendor/pipedrive (2)Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts >Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiTestPipedriveOfficialSdkCommand.phpThoughts >• TestPipedriveOfficialSdkCommand.php= C TestPipedriveOfficialSdkCommand.php2 fles 450-26>Ask anvthina (*4L)+ &CodeSWE-1.6we should use v2 with new SDK. Are you using new SDK?+ 205 tokens+16 -8+ 807 tokens2) Reject allAccept allW Windsurf Teams 14:1 (35 chars, 1 line break) UTF-8 ia 4 spaces...
|
NULL
|
-6620578790297819426
|
NULL
|
click
|
ocr
|
NULL
|
PhostormVIewINavicareCodeLaravelKeractorFV faVsco. PhostormVIewINavicareCodeLaravelKeractorFV faVsco.js?° pipedrive-sdk-poc vProiect©ActivityController.php© SyncProfileMetadata.phpCConvertLeadActivities.ongOPurgeLookupcache.pnp© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.php(C) LeadConverted.php© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd(C)AutomatedReportsRenositorv.ohd› EnqagementStatsш GeckoExport(C)AutomatedReportsCommand.ohvphp api y2.ohoC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesult.onp© AutomatedReport.phpMallboxes• Midratefinal class ActivityController extends Controller implements Commer sAAVPlavbackithemes1090public function listActivitySearch(Request $request, SearchTransformer SsealM PlavbooksPlaylists> M Postmark1093/** @var User Suser *Suser = $request->user0:> M PronhetAv M Renorts1095Sthis->response->getManagerO© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 1097© AutomatedReportsSendCommand.pht 1098© CreateMockAskJiminnyReportResultC 1099© DeleteReportCommand.php1106© GenerateMarketingReport.php© Team.php1102© Usage.php>07 Slack11194-›serserauzertnew Jsonserzalzzer00:return Sthis->response->withCollectiondsuser->searcheso->geto->withconsumer(Suser)›_ TeamsLocal ChangesLog XTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost readv one call to he tocted & filac 8 05 26 14•54) hubsnot rate limit temn checkout 17 filoc 8 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04.26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22> Don't send if no s3 path (fix update to failed) 1 file, 17.04.26, 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40• web.oho fix router 1 file. 1.04.26. 9.23Code will hoin INF to underctand vour Laravel ann code II Generate |I Don't Show Anvmore (21 minutes aao)=custom.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipearive versions vI Ap1 Fersonrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons ve Ap1 AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:= 22Dclass TestPipedrive0fficialSdkCommand extends CommandAccept Reject24 ot25266IIIIprotected Ssianature = "niminnv:test-oipedrive-official-sok «teamid-':6 usagesprivate acray edigsylt Accept File g- X Reject File t*a+ 20f2 files →Nothina to show#Daily - Platform • 10 m left100% Lz• Mon 18 May 9:55:42AskJiminnyReportActivityServiceTest v+0..Debugging PipedriveTnoughts03 tasks done•Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallableTest v2 APl endpoints with official SDKSearched v2 in vendor/pipedrive (2)Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts >Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiTestPipedriveOfficialSdkCommand.phpThoughts >• TestPipedriveOfficialSdkCommand.php= C TestPipedriveOfficialSdkCommand.php2 fles 450-26>Ask anvthina (*4L)+ &CodeSWE-1.6we should use v2 with new SDK. Are you using new SDK?+ 205 tokens+16 -8+ 807 tokens2) Reject allAccept allW Windsurf Teams 14:1 (35 chars, 1 line break) UTF-8 ia 4 spaces...
|
49735
|
NULL
|
NULL
|
NULL
|
|
49742
|
1769
|
16
|
2026-05-18T06:55:44.056254+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087344056_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com= Daily - Platform • 10 m left100% L8•Mon 18 May 9:55:43Nikolay Yankov (Presenting)+**FFleEditM Inbe07 ServProfiesC7 ISRD xTab83 ămi4000E3 Pror+ Atter XE3 мCя(a Sche x© cun x* Cia xCostoum x@мoPipehttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37L JenyC ProjectsHome | SalesforceEl Datadog * Clauseecroke!SentryL tasкLa insights & CoachinC DevO JMINNYSearch+ Create® For you© Recent|# Starred8? Apps0 Spacesauarco59 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamRequest typeStatusAssigneeMore fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterAssigneeStatusLalus droup - txec summaryP2 MediumGabriela Durevail Stelyan GeorgievANALYZINGplelleuI@ Platform team [3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base9 CustomersSRO-6853Moxso - Potential deal stagesP2 MediumSRD-6343bugSidekck SMSgsun@ lukas KovalkP2 Medium|Stoyan Tomov@ Lukas Kovalk• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Recentliminau INiaMon 18 May 9:56O caAsk RovoSteliyan GeorgievNikolay YankovTriageCreated +13/May/2613/May/26Nikolay IvanoyAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:18Lộ3...
|
NULL
|
-8582271652608378823
|
NULL
|
click
|
ocr
|
NULL
|
FirefoxFileEditViewHistoryBookmarksProfilesToolsWi FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com= Daily - Platform • 10 m left100% L8•Mon 18 May 9:55:43Nikolay Yankov (Presenting)+**FFleEditM Inbe07 ServProfiesC7 ISRD xTab83 ămi4000E3 Pror+ Atter XE3 мCя(a Sche x© cun x* Cia xCostoum x@мoPipehttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37L JenyC ProjectsHome | SalesforceEl Datadog * Clauseecroke!SentryL tasкLa insights & CoachinC DevO JMINNYSearch+ Create® For you© Recent|# Starred8? Apps0 Spacesauarco59 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamRequest typeStatusAssigneeMore fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterAssigneeStatusLalus droup - txec summaryP2 MediumGabriela Durevail Stelyan GeorgievANALYZINGplelleuI@ Platform team [3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base9 CustomersSRO-6853Moxso - Potential deal stagesP2 MediumSRD-6343bugSidekck SMSgsun@ lukas KovalkP2 Medium|Stoyan Tomov@ Lukas Kovalk• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Recentliminau INiaMon 18 May 9:56O caAsk RovoSteliyan GeorgievNikolay YankovTriageCreated +13/May/2613/May/26Nikolay IvanoyAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:18Lộ3...
|
49740
|
NULL
|
NULL
|
NULL
|
|
49743
|
1770
|
6
|
2026-05-18T06:55:46.729104+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087346729_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
6106278563745808422
|
-3642507338288554346
|
app_switch
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
PnostormcodeFV f Meet - Daily - Platform
Close tab
PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpC) ConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedReportsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Modell• MidrateA6Y1Y6 AVPlavbackithemesM PlavbooksPlaylists> M Postmark142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_ JIMINNY:18public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;T2122 0public function getActivitvSearchido: int-...=24 6t26 61public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12:29> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost readv one call to he tocted & filac 8 05 26 14•54) hubsnot rate limit temn checkout 17 filoc 8 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9:2310.00=custom.log=laravel.log4 SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmuse Jiminny Models\UserPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsapl,use Pipearive versions vI Ap1 Fersonrlelasapluse Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi confiquration:Accept Rejectuse Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons ve Apl AccLvicyrleLasaoLuse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:class TestPipedrive0fficialSdkCommand extends Commandprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.nontecter Stasasinzinn + LTest néficial Pinefaive snk Cninefaive/ninedoive) with e6 usaaesnrivate arrav Sresults = 1:Nothina to showDally - Platorm • 10m len100% 5• Mon 10 May 9:00.40AskJiminnyReportActivityServiceTest v+0..• Debugging PipedriveTnoughts03 tasks done•Check if official SDK has v2 supportUpdate POc to use SDK v2 it avallableTest v2 APl endpoints with official SDKSearched v2 in vendor/pipedrive (2)Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2Thoughts >Thouahts >Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/ApiTestPipedriveOfficialSdkCommand.phpThoughts >• TestPipedriveOfficialSdkCommand.php=• TestPipedriveOfficialSdkCommand.php2 fles 450-26>Ask anvthina (*4L)+ &CodeSWE-1.6we should use v2 with new SDK. Are you using new SDK?+ 205 tokens+16 -8869 tokens2) Reject allAccept allW Windsurf Teams.161-1UTE.8IPo 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49745
|
1769
|
17
|
2026-05-18T06:55:48.114488+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087348114_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
6010633228612407689
|
1080959010570296966
|
click
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
FirefoxFileToolsEdit→ViewHistoryCBookmarksProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)Daily - Platform - 10 m left100% <478• Mon 18 May 9:55:4700+**FFleEditM Inbe07 ServProfiesF7 ISRD xTab83 ămi4000E3 Pror+ Atter XE3 Mо x(a Sche xolCurs xI* Cia xCostoum x@мoPipe xhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37L JenyC Projects23 SSHHome | SalesforceI El Datadog * ClaudeeCrore!SentryL tasкLa insights & CoachinC DevO JMINNYSearch+ Create® For you© Recent|# Starred8? Apps0 Spacesacarco5 Service-Desk|@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamQ Search work |Request typeStatusAssignee ~More fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterAssigneeStatusLalus droup - txec summaryP2 MediumGabrieta Durevail Stelyan GeorgievANALYZINGplelleuI@ Platform team [3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base9 Customers ISkU"o00sMoxso - Potential deal stagesP2 MediumSRD-6343bugSiDeKcK SMS.I49@ lukas KovalkP2 Medium|Stoyan Tomov@ Lukas Kovalk• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Recentliminau INia8• Mon 18 May 9:56O caAsk RovoSteliyan GeorgievNikolay YankovTriageCreated +15/May/2613/May/2613/May/26Nikolay IvanovAneliya Angelova9:55 AM | Daily - Platform.••Lukas Kovalik9:22...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49744
|
1770
|
7
|
2026-05-18T06:55:50.600083+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087350600_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.27310506,"top":1.0,"width":0.010638298,"height":-0.086193085},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.07342374},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.69481385,"top":1.0,"width":0.019614361,"height":-0.06424582},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.7081117,"top":1.0,"width":0.0023271276,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.71708775,"top":1.0,"width":0.011968086,"height":-0.06424582},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.7184175,"top":1.0,"width":0.043550532,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-3888802558374160990
|
6773552773465963142
|
click
|
accessibility
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini...
|
49743
|
NULL
|
NULL
|
NULL
|
|
49746
|
1769
|
18
|
2026-05-18T06:55:53.119322+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087353119_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-5269374333914379883
|
8017030614752747158
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
FirefoxFileToolsDaily - Platform • 10 m left100% <478• Mon 18 May 9:55:52Edit→ViewHistoryBookmarksCProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)=+**FFleEditM Inbe07 ServProfiesF7 ISRD xTab83 ămiE3 Pror*Atte Xz Mo x(a Sche xol Curs x* Ciu xCost xhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37• SminnyC Projects2 SSH• Home | Salesforce•0 8IE Datadog * Claudeecrore!SentryO JMINYSearch® For you© Recent|# Starred8? Apps0 Spacesacarco(9 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamQ Search workRequest typeStatusAssignee ~More fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterLalus droup - Exec summaryP2 MediumonwurplenleuI@ Platform team 3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base% CustomersSkU-000sMoxso - Potential deal stagesP2 MediumSRD-6343Sidekick SMS issueP2 Medium|Stoyan Tomov• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting CenterArchived work itemsJiminny (Oid)Jiminny (Ne... + -402Q00 Jmi x | Q MCPPipe x8 JmQO caL taska Insights & CoachinC Dev+ CreateAsk RovoMon 18 May 9:56Steliyan GeorgievNikolay YankovAssigneei Stelyan Georgiev@ Lukas Kovalk• Lukas KovalkStatusANALYZINGKiAoToKeoivTriageCreated +13/May/2613/May/26Nikolay IvanoyAneliya Angelova9:55 AM | Daily - Platform...Lukas Kovalik9:27...
|
49745
|
NULL
|
NULL
|
NULL
|
|
49747
|
1769
|
19
|
2026-05-18T06:55:56.084645+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087356084_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-5421119778771216294
|
-8214470208005548410
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
FirefoxFileToolsDaily - Platform • 10 m left100% <78• Mon 18 May 9:55:55Edit→ViewHistoryBookmarksCProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)=+**FFleEditM Inbe07 ServProfiesF7 ISRD xTab83 ămiE3 Proe+Atter XE3 Mо x(a Sche xol Curs x* cia xCost xoumx@мoPipe xhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37L JeiyC Projects2 SSH• Home | SalesforceФ0 8IE Datadog * Claudeecrore!Sentry*xIL taskLa insights & CoachinC DevO JMINYSearch+ Create® For you© Recent|# Starred8? Apps0 Spacesacarco(9 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamQ Search workRequest typeStatusAssignee ~More fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterAssigneeLalus droup - Exec summaryP2 MediumGabrieta Durevai Stelyan GeorgievplenleuI@ Platform team 3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base% CustomersSRD-6853Moxso - Potential deal stagesP2 Medium@ Lukas KovalkSRD-6343Sidekick SMS issueP2 Medium|Stoyan Tomov• Lukas Kovalk• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Jiminny (Ne... + -QO caAsk RovoMon 18 May 9:56Steliyan GeorgievNikolay YankovStatusANALYZINGKiAoToKeoivTriageCreated +13/May/2613/May/26Nikolay IvanovAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:30...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49748
|
1769
|
20
|
2026-05-18T06:55:59.111013+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087359111_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-5269374333914379883
|
8017030614752747158
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
FirefoxFileToolsDaily - Platform - 10 m left100% <478• Mon 18 May 9:55:58Edit→ViewHistoryCBookmarksProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)=+**FFleEditM Inbe07 ServProfiesF7 ISRD xTab83 ămi.020E3 Proe+ Atter XE3 Mо x(a Sche xol Curs x* Ciu xCost xoumx@MPipe8 JmQO cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37C SminnyC Projects2 SSH• Home | SalesforceI El Datadog O * Claudeecrore!Sentry*xIL taskLa Insights & CoachinC DevO JMINYSearch+ CreateAsk Rovo® For you© Recent|# Starred8? Apps0 Spacesacarco(9 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamQ Search workRequest typeStatusAssignee ~More fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterAssigneeStatusLalus droup - Exec summaryP2 MediumGabriela Durevai Stelyan GeorgievANALYZINGplenleuI@ Platform team[> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base9 Customers ISRD-6a53Moxso - Potential deal stagesP2 Medium@ lukas KovalkREADY FOR CUSTOMIRNbugSRD-6843Sidekick SMS issueP2 Medium|Stoyan Tomos@ Lukas Kovalkrookw*• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Jiminny (Ne... + -.Mon 18 May 9:56Steliyan GeorgievNikolay YankovTriageCreated +13/May/2613/May/26Nikolay IvanovAneliya Angelova9:55 AM | Daily - PlatformLukas Kovalik9:33I11Lộ3...
|
49747
|
NULL
|
NULL
|
NULL
|
|
49749
|
1770
|
8
|
2026-05-18T06:56:07.428110+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087367428_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.27310506,"top":1.0,"width":0.010638298,"height":-0.086193085},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.07342374},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.69481385,"top":1.0,"width":0.019614361,"height":-0.06424582},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.7081117,"top":1.0,"width":0.0023271276,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.71708775,"top":1.0,"width":0.011968086,"height":-0.06424582},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.7184175,"top":1.0,"width":0.043550532,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.7330452,"top":1.0,"width":0.013464096,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.73204786,"top":1.0,"width":0.011303191,"height":-0.065043926},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Unpin Nikolay Yankov's presentation from your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else's presentation","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Zoom in","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Pin Steliyan Georgiev to your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Steliyan Georgiev","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Yankov to your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mute Nikolay Yankov's microphone","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Ivanov to your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Ivanov","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Aneliya Angelova to your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Aneliya Angelova","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"You’re continuously framed","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Backgrounds and effects","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Lukas Kovalik","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:56","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off camera","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Leave call","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat with everyone","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Meeting tools","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Your microphone is on.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
5136311375646346560
|
630697964680764176
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on.
PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpC) ConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Mode]li• Midrate46Y1Y6 APlavbackithemesM PlavbooksPlaylists> M Postmark142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;public function getActivitvSearchido: int-...=public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23l10.00=custom.loglaravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipedrive\versions\v1 \Api \PersonFieldsApi:use Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:T2122 Dclass TestPipedrive0fficialSdkCommand extends CommandAccept Reject24 6tprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.26 616 usaaesnrivate arrav Sresults = 1:Nothina to showDally - Plauorm • ym len100% 2• Mon 18 May 9:56:07AskJiminnyReportActivityServiceTest v+0 •• Debugging PipedriveAnalvzedvendor/oinedrive/oipedrive/ulb/versions/v2Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/Ap:• TestPipedriveOfficialSdkCommand.php• TestPipedriveOfficialSdkCommand.php• TestCommand dockoO docker exec docker lamo 1 oho artisan iiminnv:test-oinedrive-official-sdk 192fles 176.28>Ask anvthina (*4L)+ &CodeSWE-1.6+16 -8+32 -8Run &e Skip2) Reject allAccept all090W Windsurf Toam.14-1/25 charc 1 line hreakllUTE.R'Po. 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49750
|
1769
|
21
|
2026-05-18T06:56:11.263240+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087371263_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08944444,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.9145833,"top":0.101111114,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08944444,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.101111114,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.96666664,"top":0.101111114,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.96458334,"top":0.090555556,"width":0.023611112,"height":0.037777778},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Unpin Nikolay Yankov's presentation from your main screen","depth":13,"bounds":{"left":0.34618056,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else's presentation","depth":13,"bounds":{"left":0.37395832,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"bounds":{"left":0.4045139,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Zoom in","depth":13,"bounds":{"left":0.63090277,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"bounds":{"left":0.6642361,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"bounds":{"left":0.69756943,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Pin Steliyan Georgiev to your main screen","depth":13,"bounds":{"left":0.7607639,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.7885417,"top":0.2488889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Steliyan Georgiev","depth":13,"bounds":{"left":0.8190972,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"bounds":{"left":0.753125,"top":0.36277777,"width":0.090625,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Yankov to your main screen","depth":13,"bounds":{"left":0.8871528,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mute Nikolay Yankov's microphone","depth":13,"bounds":{"left":0.9149306,"top":0.2488889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"bounds":{"left":0.9454861,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.07673611,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Ivanov to your main screen","depth":13,"bounds":{"left":0.7607639,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.7885417,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Ivanov","depth":13,"bounds":{"left":0.8190972,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"bounds":{"left":0.753125,"top":0.6205556,"width":0.07395833,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Aneliya Angelova to your main screen","depth":13,"bounds":{"left":0.8871528,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.9149306,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Aneliya Angelova","depth":13,"bounds":{"left":0.9454861,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"bounds":{"left":0.87951386,"top":0.6205556,"width":0.088541664,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"You’re continuously framed","depth":13,"bounds":{"left":0.82256943,"top":0.7644445,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Backgrounds and effects","depth":13,"bounds":{"left":0.853125,"top":0.7644445,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Lukas Kovalik","depth":13,"bounds":{"left":0.8836806,"top":0.76666665,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"bounds":{"left":0.753125,"top":0.87833333,"width":0.06875,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"bounds":{"left":0.96631944,"top":0.875,"width":0.018055556,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:56","depth":12,"bounds":{"left":0.050347224,"top":0.9444444,"width":0.022222223,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"bounds":{"left":0.07604167,"top":0.9444444,"width":0.017361112,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"bounds":{"left":0.11076389,"top":0.9111111,"width":0.08090278,"height":0.08888888},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"bounds":{"left":0.11076389,"top":0.9444444,"width":0.08090278,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"bounds":{"left":0.32118055,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":13,"bounds":{"left":0.34895834,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"bounds":{"left":0.38784721,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off camera","depth":13,"bounds":{"left":0.415625,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"bounds":{"left":0.45451388,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"bounds":{"left":0.49895832,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"bounds":{"left":0.5434028,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"bounds":{"left":0.58784723,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"bounds":{"left":0.6322917,"top":0.9288889,"width":0.025,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Leave call","depth":12,"bounds":{"left":0.6628472,"top":0.9288889,"width":0.05,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"bounds":{"left":0.89166665,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat with everyone","depth":12,"bounds":{"left":0.925,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Meeting tools","depth":12,"bounds":{"left":0.9583333,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Your microphone is on.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
5136311375646346560
|
630697964680764176
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on.
FirefoxFileProfilesToolsWindowa Daily - Platform - 9 m left100% <78• Mon 18 May 9:56:11EditViewHistoryBookmarks→Helpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)006+**18FleTớtC7 ISREC7 (SRD83 5miE3 PromAtte x | 83 мо x(a Sche x© cun x* Ca xCost xQ мcяPipe x8 JmO cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6848L JenyC Projects* ClaudeSentry*xIC DevTAMINTY® For you© Recent|# Starred8? Apps02 Spacesauarco(9 Service-Desk@ Summary@ QueuesplenleuI@ Platform team [3> Team Priority= View all que... >Service requestsA Incidentsll Reports@ Knowledge Base9 Customers I• Channeisl8 Emall logs* Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Jiminny (Ne... + -.• Home | Salesforce• сrоkсL tasknsignts & Coachn.Search+ CreateAsk Rovo< BackSidekick SMS issueIn ProgressLink work item* Add form0 Add design~ DetailsStoyan Tomov raised this request via JiralView request in portalnosouenAssignee® Lukas KovailkAssign to meTeyteeTTScott de Zoeten from Reward Gateway-Edenred reached out to complain that he got an automated email stating that his SMS from the 10th of May was not sent toReportenStoyan Tomovone of his prospects.I tried investigating (via CloudWatch logs, Twilo messaging logs, Sentry, etc), but I couldn't find any trace of his attempted reply to that prospect ([PHONE]).To send the text message, he replied to the emall he got when the prospect texted him first:Request Type6 Report abugKnowledge base@ View reiated ....Text from 027 513 8300Priority levelP2 MediumDev TeamPlatform teamOrganizationReward Gateway-EdenredII cal you back.Canny LinksOpen Canny LinksTo send a message back, just reply to this email.~ More fieldsLabelsNone8• Mon 18 May 9:56Steliyan GeorgievNikolay YankovNikolay IvanovPREMIMASUE GOBESAneliya Angelova9:56 AM | Daily - PlatformLukas Kovalik9:45...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49751
|
1770
|
9
|
2026-05-18T06:56:39.213485+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087399213_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.27310506,"top":1.0,"width":0.010638298,"height":-0.086193085},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.07342374},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.69481385,"top":1.0,"width":0.019614361,"height":-0.06424582},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.7081117,"top":1.0,"width":0.0023271276,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.71708775,"top":1.0,"width":0.011968086,"height":-0.06424582},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.7184175,"top":1.0,"width":0.043550532,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.7330452,"top":1.0,"width":0.013464096,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.73204786,"top":1.0,"width":0.011303191,"height":-0.065043926},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Unpin Nikolay Yankov's presentation from your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else's presentation","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Zoom in","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Pin Steliyan Georgiev to your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Steliyan Georgiev","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Yankov to your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mute Nikolay Yankov's microphone","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Ivanov to your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Ivanov","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Aneliya Angelova to your main screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Aneliya Angelova","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"You’re continuously framed","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Backgrounds and effects","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Lukas Kovalik","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:56","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off camera","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Leave call","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat with everyone","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Meeting tools","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Your microphone is on.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
5136311375646346560
|
630697964680764176
|
idle
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on.
PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpC) ConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Mode]li• Midrate46Y1Y6 APlavbackithemesM PlavbooksPlaylists> M Postmark142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;public function getActivitvSearchido: int-...=public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23l10.00=custom.loglaravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipedrive\versions\v1 \Api \PersonFieldsApi:use Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:T2122 Dclass TestPipedrive0fficialSdkCommand extends CommandAccept Reject24 6tprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.26 616 usaaesnrivate arrav Sresults = 1:Nothina to showDally - Plauorm • ym len100% 2• Mon 18 May 9:56:38AskJiminnyReportActivityServiceTest v+0 •• Debugging PipedriveAnalvzedvendor/oinedrive/oipedrive/ulb/versions/v2Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/Ap:• TestPipedriveOfficialSdkCommand.php• TestPipedriveOfficialSdkCommand.php• TestCommand dockoO docker exec docker lamo 1 oho artisan iiminnv:test-oinedrive-official-sdk 192fles 176.28>Ask anvthina (*4L)+ &CodeSWE-1.6+16 -8+32 -8Run &e Skip2) Reject allAccept all090W Windsurf Toam.14-1/25 charc 1 line hreakllUTE.R'Po. 4 spaces...
|
49749
|
NULL
|
NULL
|
NULL
|
|
49752
|
1769
|
22
|
2026-05-18T06:56:44.600537+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087404600_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08944444,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.9145833,"top":0.101111114,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08944444,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.101111114,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.96666664,"top":0.101111114,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.96458334,"top":0.090555556,"width":0.023611112,"height":0.037777778},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Unpin Nikolay Yankov's presentation from your main screen","depth":13,"bounds":{"left":0.34618056,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else's presentation","depth":13,"bounds":{"left":0.37395832,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"bounds":{"left":0.4045139,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Zoom in","depth":13,"bounds":{"left":0.63090277,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"bounds":{"left":0.6642361,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"bounds":{"left":0.69756943,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Pin Steliyan Georgiev to your main screen","depth":13,"bounds":{"left":0.7607639,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.7885417,"top":0.2488889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Steliyan Georgiev","depth":13,"bounds":{"left":0.8190972,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"bounds":{"left":0.753125,"top":0.36277777,"width":0.090625,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Yankov to your main screen","depth":13,"bounds":{"left":0.8871528,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mute Nikolay Yankov's microphone","depth":13,"bounds":{"left":0.9149306,"top":0.2488889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"bounds":{"left":0.9454861,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.07673611,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Ivanov to your main screen","depth":13,"bounds":{"left":0.7607639,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.7885417,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Ivanov","depth":13,"bounds":{"left":0.8190972,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"bounds":{"left":0.753125,"top":0.6205556,"width":0.07395833,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Aneliya Angelova to your main screen","depth":13,"bounds":{"left":0.8871528,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.9149306,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Aneliya Angelova","depth":13,"bounds":{"left":0.9454861,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"bounds":{"left":0.87951386,"top":0.6205556,"width":0.088541664,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"You’re continuously framed","depth":13,"bounds":{"left":0.82256943,"top":0.7644445,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Backgrounds and effects","depth":13,"bounds":{"left":0.853125,"top":0.7644445,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Lukas Kovalik","depth":13,"bounds":{"left":0.8836806,"top":0.76666665,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"bounds":{"left":0.753125,"top":0.87833333,"width":0.06875,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"bounds":{"left":0.96631944,"top":0.875,"width":0.018055556,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:56","depth":12,"bounds":{"left":0.050347224,"top":0.9444444,"width":0.022222223,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"bounds":{"left":0.07604167,"top":0.9444444,"width":0.017361112,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"bounds":{"left":0.11076389,"top":0.9111111,"width":0.08090278,"height":0.08888888},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"bounds":{"left":0.11076389,"top":0.9444444,"width":0.08090278,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"bounds":{"left":0.32118055,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":13,"bounds":{"left":0.34895834,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"bounds":{"left":0.38784721,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off camera","depth":13,"bounds":{"left":0.415625,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"bounds":{"left":0.45451388,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"bounds":{"left":0.49895832,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"bounds":{"left":0.5434028,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"bounds":{"left":0.58784723,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"bounds":{"left":0.6322917,"top":0.9288889,"width":0.025,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Leave call","depth":12,"bounds":{"left":0.6628472,"top":0.9288889,"width":0.05,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"bounds":{"left":0.89166665,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat with everyone","depth":12,"bounds":{"left":0.925,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Meeting tools","depth":12,"bounds":{"left":0.9583333,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Your microphone is on.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
5136311375646346560
|
630697964680764176
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on.
FirefoxFileProfilesToolsWindowa Daily - Platform • 9 m left100% <78• Mon 18 May 9:56:44EditViewHistoryBookmarks→Helpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)+18Fle® For you© Recent|# Starred8? Apps( SpacesSaarco(9 Service-Desk@ Summary@ QueuesPielleuI@ Platform team 3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowiedge Base& Customers• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Jiminny (Ne... + ..TátC7 I5REC7 ISRD83 3miE3 ProM*Atte Xz Mo x(a Sche x© cuns xCost XQ мсihttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6848L JmiyC Projects• Home | Salesforce* ClaudeSentry*xITAMINNTYSearch+ Create< Back30 3К0-68441Sidekick SMS issueLink work item* Add form0 Add designStoyan Tomov raised this request via JiralView request in portalnosooToyteeTScott de Zoeten from Reward Gateway-Edenred reached out to complain that he got an automated emall stating that his SMS from the 10th of May was not sent toone of his prospects.I tried investigating (via CloudWatch logs, Twilo messaging logs, Sentry, etc), but I couldn't find any trace of his attempted reply to that prospect ([PHONE]).To send the text message, he replied to the emall he got when the prospect texted him first:Text from 027 513 8300*8• Mon 18 May 9:56II call you back.To send a message back, just reply to this email.o Pipt XJmC DevAsk RovoIn ProgressDetailsAssignee® Lukas KovailkAssign to meKOроrtnStoyan TomovRequest Type6 ReportabugKnowledge base@ View reiated ....Priority levelP2 MediumDev TeamPlatform teamOrganizationCanny LinksOpen Canny Links~ More fieldsLabelsNoneSteliyan GeorgievNikolay YankovNikolay IvanoV.e coosAneliya Angelova9:56 AM | Daily - PlatformLukas Kovalik• 10:18|111...
|
49750
|
NULL
|
NULL
|
NULL
|
|
49753
|
1769
|
23
|
2026-05-18T06:56:47.612709+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087407612_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Zoom in
Open in new window
Enter Full Screen
Steliyan Georgiev
Nikolay Yankov
Nikolay Ivanov
Aneliya Angelova
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08944444,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.9145833,"top":0.101111114,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08944444,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.101111114,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.96666664,"top":0.101111114,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.96458334,"top":0.090555556,"width":0.023611112,"height":0.037777778},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Zoom in","depth":13,"bounds":{"left":0.63090277,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"bounds":{"left":0.6642361,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"bounds":{"left":0.69756943,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"bounds":{"left":0.753125,"top":0.36277777,"width":0.090625,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.07673611,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"bounds":{"left":0.753125,"top":0.6205556,"width":0.07395833,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"bounds":{"left":0.87951386,"top":0.6205556,"width":0.088541664,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"bounds":{"left":0.753125,"top":0.87833333,"width":0.06875,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"bounds":{"left":0.96631944,"top":0.875,"width":0.018055556,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:56","depth":12,"bounds":{"left":0.050347224,"top":0.9444444,"width":0.022222223,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"bounds":{"left":0.07604167,"top":0.9444444,"width":0.017361112,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"bounds":{"left":0.11076389,"top":0.9111111,"width":0.08090278,"height":0.08888888},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"bounds":{"left":0.11076389,"top":0.9444444,"width":0.08090278,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"bounds":{"left":0.32118055,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":13,"bounds":{"left":0.34895834,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"bounds":{"left":0.38784721,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off camera","depth":13,"bounds":{"left":0.415625,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"bounds":{"left":0.45451388,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"bounds":{"left":0.49895832,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"bounds":{"left":0.5434028,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"bounds":{"left":0.58784723,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"bounds":{"left":0.6322917,"top":0.9288889,"width":0.025,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Leave call","depth":12,"bounds":{"left":0.6628472,"top":0.9288889,"width":0.05,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"bounds":{"left":0.89166665,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat with everyone","depth":12,"bounds":{"left":0.925,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Meeting tools","depth":12,"bounds":{"left":0.9583333,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Your microphone is on.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
5219402422117062273
|
1643948537811360532
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Zoom in
Open in new window
Enter Full Screen
Steliyan Georgiev
Nikolay Yankov
Nikolay Ivanov
Aneliya Angelova
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is on.
FirefoxFileEditViewHistoryBookmarksProfilesToolsWindow→Helpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)a Daily - Platform • 9 m left100% <78• Mon 18 May 9:56:47+**18FleTátM InboC7 I5REC7 (SRD83 3miE3 ProM+Ate Xz Mo x(a Sche x© Cuns xCost xQ мcHhttps://fminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6848- JeiyC Projects*xIJIMINNY® For you© Recent|# Starred8? AppsQ Spacesacarco(9 Service-Desk@ Summary|@ QueuespielleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentsll Reports@ Knowiedge Base& Customers• Channeisl8 Emall logs% Developer escalati..f: Slack integration§ Reporting Center8 Archived work itemsJiminny (Oid)Jiminny (Ne... + -.• Home | Salestorce* CauờiSentrySearch+ Create< BackSidekick SMS issueLink work item* Add form0 Add designStoyan Tomov raised this request via JiralView request in portalnooeoScott de Zoeten from Reward Gateway-Edenred reached out to complain that he got an automated emall stating that his SMS from the 10th of May was not sent toone of his prospects.I tried investigating (via CloudWatch logs, Twilo messaging logs, Sentry, etc), but I couldn't find any trace of his attempted reply to that prospect ([PHONE]).To send the text message, he replied to the emall he got when the prospect texted him first:Text from 027 513 8300II call you back.To send a message back, just reply to this email.Mon 18 May 9:56o Pipt XC DevAsk RovoIn ProgressDetailsAssignee® Lukas KovailkAssign to meKOpоrtnStoyan TomovRequest Type6 Report abugKnowledge base@ View reiated ....Priority levelP2 MediumDev Team |Platform teamOrganizationCanny LinksOpen Canny LinksMore fieldsLabelsNoneSteliyan GeorgievNikolay YankovNikolay,vanoVuE sousAneliya Angelova9:56 AM | Daily - PlatformLukas Kovalik• 10:21|...
|
49750
|
NULL
|
NULL
|
NULL
|
|
49754
|
1769
|
24
|
2026-05-18T06:56:50.638309+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087410638_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-7861119642317981253
|
1080994049047840390
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
+FirefoxFileEditViewHistoryBookmarksProfilesToolsWindowHelpa Daily - Platform • 9 m left100% <78• Mon 18 May 9:56:50→meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)FleC7 ISRET7 (SRD83 5miE3 PronAtte: x | 83 мс x[a Sche x | © Cun x* Oa xCost X"0.0 Jmi x : Q MCP8• Mon 18 May 9:56Pipe x8 JmO cahttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37/SRD-6848L JeenyC Projects• Home | SalesforceD0©csO CircieciSentry*xIL tasкC DevJIMINNYSearch+ CreateAsk Rovo® For you© Recent|# Starred8? AppsQ SpacesSaarco5 Service-Desk|@ Summary@ Queues< Back30 3К0-68441Sidekick SMS issueIn ProgressLink work item* Add form0 Add designDetails@ Stoyan Tomov raised this request via JlraView request in portalHide detallsScott de Zoeten from Reward Gateway-Edenred reached out to complain that he got an automated emall stating that his SMS from the 10th of May was not sent toAssignee® Lukas KovailkAssign to meReporter& Stoyan TomovF-18pielleuI@ Platform team> Team Priority= View all que... >Service requestsA Incidentsll Reports@ Knowiedge Base& Customers• Channeisl8 Emall logs% Developer escalati..f: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)one of his prospects.I tried investigating (via CloudWatch logs, Twilo messaging logs, Sentry, etc), but I couldn't find any trace of his attempted reply to that prospect ([PHONE]).|To send the text message, he replied to the emall he got when the prospect texted him first:Request Type6 Report abugKnowledge base© View related ....Text from 027 513 8300Priority levelP2 Medium|Dev TeamPlatform teamOrganizationReward Gateway-EdenredII call you back.Cannry LinksOpen Canny LinksTo send a message back, just reply to this omail.More fieldsLabelsNoneJiminny (Ne... + -.Steliyan GeorgievNikolay. Ivanov eices=Nikolay YankovAneliya AngelovaTurn off microphone (98 + d)9:56 AM | Daily - PlatformLukas Kovalik• 10:24|Lộ3...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49755
|
1769
|
25
|
2026-05-18T06:56:53.673576+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087413673_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
2241554596966511350
|
936754074857264774
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
FirefoxFileToolsEdit→ViewHistoryCBookmarksProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)a Daily - Platform • 9 m left100% <78• Mon 18 May 9:56:53=+FFleEdit57 SenC7 ISRD xTab83 ămiY04Q0E3 ProeAlte x | 83 мо x[l Sche x Cun x1 * cia xCost XOum x@vo x.Pipe xhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/queues/custom/37L JeenyC ProjectsE3 SSH• Home | Salesforce•0 8 NEdtd 0@ * cuude O Crclalsetry &xL tasкnsignts & Coachn.C DevJIMINNYSearch+ Create® For you© Recent|# Starred8? AppsO SpacesSurco(9 Service-Desk@ Summary@ QueuesSpaces / Service-Desk / QueuesPlatform teamQ Search workRequest typeStatusAssignee ~More fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterAssigneeLalus droup" txec summaryP2 MediumGabrieta Durevai Stellyan GeorgievplelleuI@ Platform team 3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base9 Customers ISkU-o00sMoxso - Potential deal stagesP2 Medium@ lukas KovalkSRD-6343Sidekick SMS issueP2 Medium|Stoyan Tomov@ Lukas Kovalk• Channeisl8 Emall logs% Developer escalati..if: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Jiminny (Ne... + -.QAsk RovoMon 18 May 9:56Steliyan GeorgievNikolay YankovStatusANALYZINOINPROCRES ETriageCreated +13/May/2613/May/26Nikolay, Ivanovc0005Aneliya Angelova9:56 AM | Daily - PlatformTurn off microphone (86 + d).••Lukas Kovalik10:27111...
|
49754
|
NULL
|
NULL
|
NULL
|
|
49756
|
1769
|
26
|
2026-05-18T06:56:56.684985+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087416684_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Zoom in
Open in new window
Enter Full Screen
Steliyan Georgiev
Nikolay Yankov
Nikolay Ivanov
Aneliya Angelova
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Turn off microphone (⌘ + d)
Your microphone is on....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08944444,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.9145833,"top":0.101111114,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08944444,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.101111114,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.96666664,"top":0.101111114,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.96458334,"top":0.090555556,"width":0.023611112,"height":0.037777778},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Zoom in","depth":13,"bounds":{"left":0.63090277,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"bounds":{"left":0.6642361,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"bounds":{"left":0.69756943,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"bounds":{"left":0.753125,"top":0.36277777,"width":0.090625,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.07673611,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"bounds":{"left":0.753125,"top":0.6205556,"width":0.07395833,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"bounds":{"left":0.87951386,"top":0.6205556,"width":0.088541664,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"bounds":{"left":0.753125,"top":0.87833333,"width":0.06875,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"bounds":{"left":0.96631944,"top":0.875,"width":0.018055556,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:56","depth":12,"bounds":{"left":0.050347224,"top":0.9444444,"width":0.022222223,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"bounds":{"left":0.07604167,"top":0.9444444,"width":0.017361112,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"bounds":{"left":0.11076389,"top":0.9111111,"width":0.08090278,"height":0.08888888},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"bounds":{"left":0.11076389,"top":0.9444444,"width":0.08090278,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"bounds":{"left":0.32118055,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":13,"bounds":{"left":0.34895834,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"bounds":{"left":0.38784721,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off camera","depth":13,"bounds":{"left":0.415625,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"bounds":{"left":0.45451388,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"bounds":{"left":0.49895832,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"bounds":{"left":0.5434028,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"bounds":{"left":0.58784723,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"bounds":{"left":0.6322917,"top":0.9288889,"width":0.025,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Leave call","depth":12,"bounds":{"left":0.6628472,"top":0.9288889,"width":0.05,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"bounds":{"left":0.89166665,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat with everyone","depth":12,"bounds":{"left":0.925,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Meeting tools","depth":12,"bounds":{"left":0.9583333,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Turn off microphone (⌘ + d)","depth":10,"bounds":{"left":0.31180555,"top":0.9027778,"width":0.10729167,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your microphone is on.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-343141145364252736
|
1643948400435845908
|
visual_change
|
accessibility
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Zoom in
Open in new window
Enter Full Screen
Steliyan Georgiev
Nikolay Yankov
Nikolay Ivanov
Aneliya Angelova
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:56
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Turn off microphone (⌘ + d)
Your microphone is on....
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49757
|
1769
|
27
|
2026-05-18T06:56:59.710319+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087419710_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08944444,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.9145833,"top":0.101111114,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08944444,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.101111114,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.96666664,"top":0.101111114,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
8963349859095646583
|
5620626870812596358
|
visual_change
|
accessibility
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini...
|
49756
|
NULL
|
NULL
|
NULL
|
|
49758
|
1769
|
28
|
2026-05-18T06:57:02.734105+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087422734_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Zoom in
Open in new window
Enter Full Screen
Steliyan Georgiev
Nikolay Yankov
Nikolay Ivanov
Aneliya Angelova
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:57
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Turn off microphone (⌘ + d)
Your microphone is on....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08944444,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.9145833,"top":0.101111114,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08944444,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.101111114,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.96666664,"top":0.101111114,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.96458334,"top":0.090555556,"width":0.023611112,"height":0.037777778},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Zoom in","depth":13,"bounds":{"left":0.63090277,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"bounds":{"left":0.6642361,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"bounds":{"left":0.69756943,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"bounds":{"left":0.753125,"top":0.36277777,"width":0.090625,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.07673611,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"bounds":{"left":0.753125,"top":0.6205556,"width":0.07395833,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"bounds":{"left":0.87951386,"top":0.6205556,"width":0.088541664,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"bounds":{"left":0.753125,"top":0.87833333,"width":0.06875,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"bounds":{"left":0.96631944,"top":0.875,"width":0.018055556,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:57","depth":12,"bounds":{"left":0.050347224,"top":0.9444444,"width":0.021527778,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"bounds":{"left":0.07534722,"top":0.9444444,"width":0.017708333,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"bounds":{"left":0.110416666,"top":0.9111111,"width":0.08055556,"height":0.08888888},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"bounds":{"left":0.110416666,"top":0.9444444,"width":0.08055556,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"bounds":{"left":0.32118055,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":13,"bounds":{"left":0.34895834,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"bounds":{"left":0.38784721,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off camera","depth":13,"bounds":{"left":0.415625,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"bounds":{"left":0.45451388,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"bounds":{"left":0.49895832,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"bounds":{"left":0.5434028,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"bounds":{"left":0.58784723,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"bounds":{"left":0.6322917,"top":0.9288889,"width":0.025,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Leave call","depth":12,"bounds":{"left":0.6628472,"top":0.9288889,"width":0.05,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"bounds":{"left":0.89166665,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat with everyone","depth":12,"bounds":{"left":0.925,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Meeting tools","depth":12,"bounds":{"left":0.9583333,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Turn off microphone (⌘ + d)","depth":10,"bounds":{"left":0.31180555,"top":0.9027778,"width":0.10729167,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your microphone is on.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-1434399206636850857
|
1499833212367854356
|
visual_change
|
accessibility
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Zoom in
Open in new window
Enter Full Screen
Steliyan Georgiev
Nikolay Yankov
Nikolay Ivanov
Aneliya Angelova
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:57
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Turn off microphone (⌘ + d)
Your microphone is on....
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49759
|
1770
|
10
|
2026-05-18T06:57:11.184289+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087431184_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Zoom in
Open in new window
Enter Full Screen
Steliyan Georgiev
Nikolay Yankov
Nikolay Ivanov
Aneliya Angelova
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:57
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Turn off microphone (⌘ + d)
Your microphone is on....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.27310506,"top":1.0,"width":0.010638298,"height":-0.086193085},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.07342374},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.69481385,"top":1.0,"width":0.019614361,"height":-0.06424582},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.7081117,"top":1.0,"width":0.0023271276,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.71708775,"top":1.0,"width":0.011968086,"height":-0.06424582},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.7184175,"top":1.0,"width":0.043550532,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.7330452,"top":1.0,"width":0.013464096,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.73204786,"top":1.0,"width":0.011303191,"height":-0.065043926},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Zoom in","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:57","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off microphone","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off camera","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Leave call","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat with everyone","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Meeting tools","depth":12,"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Turn off microphone (⌘ + d)","depth":10,"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Your microphone is on.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
-1434399206636850857
|
1499833212367854356
|
idle
|
accessibility
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Zoom in
Open in new window
Enter Full Screen
Steliyan Georgiev
Nikolay Yankov
Nikolay Ivanov
Aneliya Angelova
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:57
AM
Daily - Platform
Daily - Platform
Audio settings
Turn off microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Turn off microphone (⌘ + d)
Your microphone is on....
|
49749
|
NULL
|
NULL
|
NULL
|
|
49760
|
1769
|
29
|
2026-05-18T06:57:20.231643+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087440231_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"}]...
|
-7490973366999408086
|
1080923680169285254
|
click
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
FirefoxFileToolsEdit→ViewHistoryBookmarksCProfilesWindowHelpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)Daily - Platform - 8 m left100% <78• Mon 18 May 9:57:19=+-18FleEdit57 SerProfiesN7 ISRD xTab83 5miY04Q0E3 PronC Alte x | 83 мс x(a Sche x © Cuns x*Oa X Cost XOum x@vo x.Pipe xhttps://fiminny.atlassian.net/jra/servicedesk/projects/SRD/summaryL JenyC Projects23 SSH• Home | Salestorce•0 8 NEdtd 0@ * caus O CrcleaD setry &xL tasкnsignts & Coachn.C DevJIMINNYSearch+ Create® For you© Recent|# Starred8? AppsO SpacesSuarco(9 Service-Desk@ Summary@ Queues|Spaces / Service-Desk / QueuesPlatform teamQ Search workRequest type ~StatusAssignee ~More fiters ~3 work itemsKeySummaryPriority levelSeverity levelReporterAssigneeStatusLalus droup" txec summaryP2 MediumGabriela Durevai Stellyan GeorgievANALYZINGplenleuI@ Platform team [3> Team Priority= View all que... >Service requestsA Incidentslal Reports@ Knowledge Base9 CustomersSkU"o00sMoxso - Potential deal stagesP2 Medium@ lukas KovalkSRD-6343Sidekick SMS issueP2 Medium|Stoyan Tomov@ Lukas Kovalk"ooaoy• Channeisl8 Emall logs% Developer escalati..f: Slack Integration§ Reporting Center8 Archived work itemsJiminny (Oid)Jiminny (Ne... + -.QAsk RovoMon 18 May 9:57Steliyan GeorgievNikolay YankovTriageCreated +13/May/2613/May/26Nikolay Ivanoy coasAneliya Angelova9:57 AM | Daily - PlatformTurn off microphone (98 + d)...Lukas Kovalik• 10:54...
|
49758
|
NULL
|
NULL
|
NULL
|
|
49761
|
1770
|
11
|
2026-05-18T06:57:20.231698+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087440231_m2.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_2
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.27027926,"top":1.0,"width":0.016123671,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.27094415,"top":1.0,"width":0.004986702,"height":-0.051875472},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.27310506,"top":1.0,"width":0.010638298,"height":-0.086193085},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.072625756},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.30634972,"top":1.0,"width":0.059507977,"height":-0.07342374},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.69481385,"top":1.0,"width":0.019614361,"height":-0.06424582},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false}]...
|
5129730573215277865
|
1008936454875562630
|
click
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
PnostormcodeFV faVsco.js?9 pipedrive-sdk-poc vProiectC ActivityController.ong© SyncProfileMetadata.phpC) ConvertLeadActivities.ong© SyncPlanhat.php©syncleammetadata.ong© TestPipedriveOfficialSdkCommand.phUpoateopponunityspecrications.ono>@ Dealinsights>@Dev> 0 DialerscreatePlaybookcreatedevent.ong©) salestorce/service.phpc) IntearationApp/Service.phpC) LeadConverted.ohg© CreateSelfCoachedEvent.phpD DTOSC ElasticsearchC) CreateCommentedEvent.phoC) CreateSmsSentEvent.ohpC) PlanhatActivityListener.pho(C)AskAnvthinaPromotService.ohd› EnqagementStatsш GeckoExportC) AutomatedRenortsCommand.ohophp api y2.ohdC) RequestGenerateReport.Job.oho/>D Livestream(C) AutomatedReportkesulconp•AutomatedRenort nhn XiMallboxesclass AutomatedRenont extends Mode]li• Midrate46Y1Y6 APlavbackithemesM PlavbooksPlaylists> M Postmark142143return Sthis->getType === AutomatedReportsService::TYPE_ASK_JIMINNY:public function isExpired: boolf...}> M PronhetAv M Renorts© AutomatedReportsCommand.php© AutomatedReportsRetentionPolicyCor 16© AutomatedReportsSendCommand.pht© CreateMockAskJiminnyReportResultC© DeleteReportCommand.php© GenerateMarketingReport.php© Team.php© Usage.php172>07 Slackpublic function canExecute@: boolf...;public function getActivitvSearchido: int-...=public function getAskAnvthingPromptIdO: 2intf...}nublic function aetExoiresAtO: 2Carhons...›_ TeamsLocal ChangesLog xTIO+→?> JY-20891 SMS Text relay EU 3 files, 15.05.26, 14:05• ID 8 CondPenart loh 2 filec 12 05 26 12.291> reorder calle 1 file 11.05 26 10•00› Move non paginator search calls to client->search 1 file, 11.05.26, 10:07) Almost ready one call ta he tocted & filoc 8 05 26 14-54) hubsnot rate limit temn checkout 17 filac 9 05 26 11:19› saved search delete 1 file, 27.04.26, 14:58> expiration message 6 files, 27.04.26, 9:23> UP dev logs 1 file, 24.04.26, 12:02› tem test 1 file, 24.04.26, 10:36› user transformer 3 files, 23.04.26. 15:43> email ready 9 files. 23.04.26. 15:31> Email on not sent 5 files. 21.04,26, 19:38> Planhat track interest event 2 files. 21.04.26. 13:56> UP trackina controller 1 file. 20.04.26. 9:22• Don't send it no s3 path (tix uodate to tailed) 1 tile. 17.04.26. 12:56)> FEATURE CHANGES 3 files. 6.04. 26. 13:40> web.oho fix router 1 file. 1.04.26. 9.23l10.00=custom.loglaravel.logA SF [jiminny@localhost]& console (STAGINGIA HS_local [jiminny@localhost]A console [PROD]© TestPipedriveOfficialSdkCommand.php X © Kernel.phpconsole EUuse Jiminny models redmPipedrive|versions|v1\Api\ActivitiesApi;ActivityFieldsApi;use Pipedrive verstons velape beatrielasapt,use Pipedrive verstons velapt beatsaptyuse Pipedrive\versions\v1 \Api \PersonFieldsApi:use Pipearive versions vI Ap1 Fersonsapluse Pioedrive versions vi Confiquration:use Pipedrive versions\v2\Api ActivitiesApi:use rrpearive verszons Ve Ap1 AcuLvicyrleLasapluse Pipedrive versions\v2\Api DealFieldsApi:use Pipearive versions vz Ap1 UealSAp1*use Pipedrive versions\v2\Api PersonFieldsApi:use Pipearive versions vz Ap1 PersonsAp1*use Pipedrivel versions|v2\ Confiquration:T2122 Dclass TestPipedrive0fficialSdkCommand extends CommandAccept Reject24 6tprotected Ssianature = "niminnv:test-pipedrive-official-sok teamid-'.26 616 usaaesnrivate arrav Sresults = 1:Nothina to showDally - Plauorm• om lemt100% 2• Mon 18 May 9:57:19AskJiminnyReportActivityServiceTest v+0 •• Debugging PipedriveAnalvzedvendor/oinedrive/oipedrive/ulb/versions/v2Analyzed vendor/pipedrive/pipedrive/lib/versions/v2/Ap:• TestPipedriveOfficialSdkCommand.php• TestPipedriveOfficialSdkCommand.php• TestCommand dockoO docker exec docker lamo 1 oho artisan iiminnv:test-oinedrive-official-sdk 192fles 176.28>Ask anvthina (*4L)+ &CodeSWE-1.6+16 -8+32 -8Run &e Skip2) Reject allAccept all090W Windsurf Toam.14-1/25 charc 1 line hreakllUTE.R'Po. 4 spaces...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49762
|
1769
|
30
|
2026-05-18T06:57:22.212973+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087442212_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-5421119778771216294
|
-8214470208005548410
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
+FirefoxProfilesToolsWindow$*(18FileEditViewHistoryBookmarksHelp→meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)TátT7 (SRD83 5mi* PrO+ Atter XE3 мСI(a Sche x© Cuns xOum xQ мcяo Pipt X8 Jmhttps://fiminny.atlassian.net/jra/software/c/projects/JJY/boards/37C Projects• Home | Salesforce•0 8Datadog*xIC DevJIMINNYSearch+ CreateAsk Rovo® For you© Recent|# Starred8? Apps0 SpacesSuurco(9 Service-Desk@ Summary|@ Queues|Service requestsA Incidentslal Reports@ Knowiedge Base& CustomersChanneis8 Email logsSpaces / 'Jiminny (New)Platform Team %.@ SummaryE BackdogaI) Active sprints83 CalanderReportsTesting Board# ListE Forms• Components |% Devetopment% CodeO SecurityMore 7|800018EpicvTypeyREADY FOR DEV 4ENOEV 3COOE REVIEWBEUSAQA 3PU ALNAPanorama prompts isyera as of cals andMCP > Enabie the AI toknow dotalls about theCRM rematching onScoring in ODARPORTS2030003•еe.=ANONVY MCP CONNICTONIn Dev9 .s0=Д JY-20878Д 3y-20833JMINNY MCР CONNECTORCode Revea15 П ***=R s-2084ePLATFORM STARILTYIn OA151aee =|a5 • ***=Д 31-20381O JY-20225Notity the user it a SSis deleted but is used inAJ ReportARPORTSMCP > Enable users toget a list of deais andtheir detailsLARDCYCONGSTOUpgrade to PHP 8.5PHR KSUPORADE(Deadiine 25 May]Migrate depricatedGemini 3.1 Flash Lite….Fif: Slack IntegrationReporting Cente!Archived work temsJiminny (Old)20 й ***=wJr-l4ootHJ-2001544-20435Upgrade Python andJoranies " MayUpglade bt lbranesAon owner s 1oi 10.Hocuiet in sonarIn QAseung up a thaiEMPROVEMENT OF OUR EFFIC1 CD Platform Team1se00 =# JY-20831©3-199518 J-19958|Д 37-20613Enterprise StablltyCID Processing TeamImprove Activity Type[Deadiine 17 June]Migrate depricatedDaily - Platform - 8 m left100% C8• Mon 18 May 9:57:21Ota=Mon 18 May 9:57Steliyan GeorgievNikolay YankovNikolay vanoy coosAneliya Angelova9:57 AM |Daily - PlatformLukas Kovalik10:56...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49763
|
1769
|
31
|
2026-05-18T06:57:26.835260+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087446835_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false}]...
|
-5269374333914379883
|
8017030614752747158
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
+FirefoxProfilesToolsWindowDaily - Platform - 8 m left100% <47FileEditViewHistoryBookmarksHelp→meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)TátMon 18 May 9:57YSRD83 5mi* PrO+ Atter XE3 мCя(a Sche x© CursCost x© JimiQ мсяo Pipe|O cahttps://fiminny.atlassian.net/jra/software/c/projects/JJY/boards/3788— УrорстяE DatadogL taskC DevL Al BookmarksPlatform Team %Q Search board8800018Epic ~TypeQuick fittersGroup: QuerienPOADOTANotify the user d aMCP > Enabie users to get[HubSpot) Optimise CRM|AJREFORTSBacklogQJY-20676know detatis sbout the userJMDINY MCР CONNECTORJIMENNEC MCP CONNECTORIn DevR J-20833Д -л-20846 15 12 ***= ®hubspot accounts/contactsCLATFORM STARTUTINIn OA|X0E -20725 15 12 .*.•:AJ Panorama for Call|Scoring nou(NUTOMATID AL SCORINODeployedД Jy-20301 /053 .00 =0[Deadline 25 May) Migratedepricated Gemini 3.1 FlashNotity the user it a SS isdeieted but is used in AJReportAREPORTSBacklogA JY-20815|25 4000=MCP > Enable users to getauwror ocals and trewdetallsJEMENNY NOS CONNECTOSIn Dev@ 37-20835 20 1 ***=Upgrade to PHP 8.5PHP 8.S UPORADEReady for QA©J-non 1s 1 **=OД 3-20850 1 П1 ***=*Upgrade Python andlbraries - May|MAINTENANONSetup test coverage forProchet in Sonar|Upgrade BE Ibraries - MayMAINTENANICSВаскіюяіE JY-199581 •=•Allow owner's role to beselected when setting up aENPROVIMINT OF CUR EFTRICDINGYIn Dev8. JY-20513115 = ®MSYosDeployedJY-19951 10 a00=Emprove Acuvity lypelsuggestionsAUTO-OUTECTED ACTIVITY TYPI Jy-204102 .020=E Jy-20272Sidekick SMS issueDeployed10 P-2000n •=€8• Mon 18 May 9:57:26Steliyan GeorgievNikolay vanoy coas=Nikolay YankovAneliya Angelova9:57 AM | Daily - PlatformLukas Kovalik• 11:01|...
|
49762
|
NULL
|
NULL
|
NULL
|
|
49764
|
1769
|
32
|
2026-05-18T06:57:29.843536+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087449843_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:57
AM
Daily - Platform
Daily - Platform
Audio settings
Turn on microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is off....
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08944444,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.9145833,"top":0.101111114,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08944444,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.101111114,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.96666664,"top":0.101111114,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.96458334,"top":0.090555556,"width":0.023611112,"height":0.037777778},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Unpin Nikolay Yankov's presentation from your main screen","depth":13,"bounds":{"left":0.34618056,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else's presentation","depth":13,"bounds":{"left":0.37395832,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"bounds":{"left":0.4045139,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Zoom in","depth":13,"bounds":{"left":0.63090277,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"bounds":{"left":0.6642361,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"bounds":{"left":0.69756943,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Pin Steliyan Georgiev to your main screen","depth":13,"bounds":{"left":0.7607639,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.7885417,"top":0.2488889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Steliyan Georgiev","depth":13,"bounds":{"left":0.8190972,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"bounds":{"left":0.753125,"top":0.36277777,"width":0.090625,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Yankov to your main screen","depth":13,"bounds":{"left":0.8871528,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mute Nikolay Yankov's microphone","depth":13,"bounds":{"left":0.9149306,"top":0.2488889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"bounds":{"left":0.9454861,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.07673611,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Ivanov to your main screen","depth":13,"bounds":{"left":0.7607639,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.7885417,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Ivanov","depth":13,"bounds":{"left":0.8190972,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"bounds":{"left":0.753125,"top":0.6205556,"width":0.07395833,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Aneliya Angelova to your main screen","depth":13,"bounds":{"left":0.8871528,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.9149306,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Aneliya Angelova","depth":13,"bounds":{"left":0.9454861,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"bounds":{"left":0.87951386,"top":0.6205556,"width":0.088541664,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"You’re continuously framed","depth":13,"bounds":{"left":0.82256943,"top":0.7644445,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Backgrounds and effects","depth":13,"bounds":{"left":0.853125,"top":0.7644445,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Lukas Kovalik","depth":13,"bounds":{"left":0.8836806,"top":0.76666665,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"bounds":{"left":0.753125,"top":0.87833333,"width":0.06875,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"bounds":{"left":0.96631944,"top":0.875,"width":0.018055556,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:57","depth":12,"bounds":{"left":0.050347224,"top":0.9444444,"width":0.021527778,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"bounds":{"left":0.07534722,"top":0.9444444,"width":0.017708333,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXHeading","text":"Daily - Platform","depth":12,"bounds":{"left":0.110416666,"top":0.9111111,"width":0.08055556,"height":0.08888888},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Daily - Platform","depth":15,"bounds":{"left":0.110416666,"top":0.9444444,"width":0.08055556,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Audio settings","depth":13,"bounds":{"left":0.32118055,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on microphone","depth":13,"bounds":{"left":0.34895834,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":true,"is_selected":false},{"role":"AXButton","text":"Video settings","depth":13,"bounds":{"left":0.38784721,"top":0.9288889,"width":0.06111111,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn off camera","depth":13,"bounds":{"left":0.415625,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Nikolay Yankov is presenting","depth":12,"bounds":{"left":0.45451388,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Send a reaction","depth":12,"bounds":{"left":0.49895832,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Turn on captions","depth":13,"bounds":{"left":0.5434028,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Raise hand (ctrl + ⌘ + h)","depth":12,"bounds":{"left":0.58784723,"top":0.9288889,"width":0.03888889,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options","depth":12,"bounds":{"left":0.6322917,"top":0.9288889,"width":0.025,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Leave call","depth":12,"bounds":{"left":0.6628472,"top":0.9288889,"width":0.05,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Meeting details","depth":12,"bounds":{"left":0.89166665,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Chat with everyone","depth":12,"bounds":{"left":0.925,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Meeting tools","depth":12,"bounds":{"left":0.9583333,"top":0.9288889,"width":0.033333335,"height":0.053333335},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Your microphone is off.","depth":8,"on_screen":false,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
8895258657628958075
|
-9164631224841676272
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:57
AM
Daily - Platform
Daily - Platform
Audio settings
Turn on microphone
Video settings
Turn off camera
Nikolay Yankov is presenting
Send a reaction
Turn on captions
Raise hand (ctrl + ⌘ + h)
More options
Leave call
Meeting details
Chat with everyone
Meeting tools
Your microphone is off.
FirefoxFileProfilesToolsWindowDaily - Platform - 8 m left100% <478• Mon 18 May 9:57:29EditViewHistoryBookmarks→Helpmeet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)=+88Platform Team %Q Search boardADTYOKWENotify the user it aAJREPORTSBacklogД Jy-200763 ...0 =Notify the user if a SS isdeleted but is used in AJReportAJREPORTSBacklogA JY-20615|2.5 •000 =Upgrade BE Ibraries - MayMAINTENANCEваскіюяіE JY-199581••= ©Amprove Acuvity lypelsuggestionsAUTO-OETEGTED AGTIVITY TYPД SY-204702 .*= 1YSRD83 5mi* PrO+ Atter XIE3 мсР[URL_WITH_CREDENTIALS] GeorgievNikolay YankovNikolay Manoy cousAneliya Angelova9:57 AM | Daily - PlatformLukas Kovalik• 11:04111...
|
NULL
|
NULL
|
NULL
|
NULL
|
|
49765
|
1769
|
33
|
2026-05-18T06:57:32.895824+00:00
|
/Users/lukas/.screenpipe/data/data/2026-05-18/1779 /Users/lukas/.screenpipe/data/data/2026-05-18/1779087452895_m1.jpg...
|
Firefox
|
Meet - Daily - Platform — Work
|
1
|
meet.google.com/agt-teir-cwt?authuser=lukas.kovali meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.com...
|
monitor_1
|
NULL
|
NULL
|
NULL
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:57
AM...
|
[{"role":"AXRadioButton","text [{"role":"AXRadioButton","text":"Meet - Daily - Platform","depth":4,"bounds":{"left":0.0,"top":0.072222225,"width":0.033680554,"height":0.045555554},"on_screen":true,"help_text":"","role_description":"tab","subrole":"AXTabButton","is_enabled":true,"is_focused":false,"is_selected":true},{"role":"AXButton","text":"Close tab","depth":5,"bounds":{"left":0.0013888889,"top":0.072222225,"width":0.010416667,"height":0.016666668},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"New Tab","depth":4,"bounds":{"left":0.005902778,"top":0.12,"width":0.022222223,"height":0.035555556},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open Google Gemini (⌃X)","depth":6,"bounds":{"left":0.0,"top":0.7977778,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Tabs from other devices","depth":6,"bounds":{"left":0.0,"top":0.8411111,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open history (⇧⌘H)","depth":6,"bounds":{"left":0.0,"top":0.8794444,"width":0.033680554,"height":0.03888889},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Open bookmarks (⌘B)","depth":6,"bounds":{"left":0.0,"top":0.91833335,"width":0.033680554,"height":0.038333334},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXCheckBox","text":"Customize sidebar","depth":6,"bounds":{"left":0.0,"top":0.95666665,"width":0.033680554,"height":0.043333333},"on_screen":true,"help_text":"","role_description":"toggle button","subrole":"AXToggle","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXHeading","text":"Nikolay Yankov (Presenting)","depth":12,"bounds":{"left":0.07534722,"top":0.101111114,"width":0.124305554,"height":0.022222223},"on_screen":true,"help_text":"","role_description":"heading","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Nikolay Yankov (Presenting)","depth":13,"bounds":{"left":0.07534722,"top":0.10222222,"width":0.124305554,"height":0.020555556},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"People","depth":15,"bounds":{"left":0.88680553,"top":0.08944444,"width":0.04097222,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"6","depth":22,"bounds":{"left":0.9145833,"top":0.101111114,"width":0.0048611113,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Take notes with Gemini","depth":14,"bounds":{"left":0.93333334,"top":0.08944444,"width":0.025,"height":0.04},"on_screen":true,"role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Take notes with Gemini","depth":17,"bounds":{"left":0.9361111,"top":0.101111114,"width":0.06388891,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"Gemini","depth":22,"bounds":{"left":0.96666664,"top":0.101111114,"width":0.028125,"height":0.017222222},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Gemini","depth":21,"bounds":{"left":0.96458334,"top":0.090555556,"width":0.023611112,"height":0.037777778},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Unpin Nikolay Yankov's presentation from your main screen","depth":13,"bounds":{"left":0.34618056,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else's presentation","depth":13,"bounds":{"left":0.37395832,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"bounds":{"left":0.4045139,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Zoom in","depth":13,"bounds":{"left":0.63090277,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Open in new window","depth":13,"bounds":{"left":0.6642361,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Enter Full Screen","depth":13,"bounds":{"left":0.69756943,"top":0.78333336,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Pin Steliyan Georgiev to your main screen","depth":13,"bounds":{"left":0.7607639,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.7885417,"top":0.2488889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Steliyan Georgiev","depth":13,"bounds":{"left":0.8190972,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Steliyan Georgiev","depth":17,"bounds":{"left":0.753125,"top":0.36277777,"width":0.090625,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Yankov to your main screen","depth":13,"bounds":{"left":0.8871528,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"Mute Nikolay Yankov's microphone","depth":13,"bounds":{"left":0.9149306,"top":0.2488889,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Yankov","depth":13,"bounds":{"left":0.9454861,"top":0.25111112,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Yankov","depth":17,"bounds":{"left":0.87951386,"top":0.36277777,"width":0.07673611,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Nikolay Ivanov to your main screen","depth":13,"bounds":{"left":0.7607639,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.7885417,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Nikolay Ivanov","depth":13,"bounds":{"left":0.8190972,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Nikolay Ivanov","depth":17,"bounds":{"left":0.753125,"top":0.6205556,"width":0.07395833,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Pin Aneliya Angelova to your main screen","depth":13,"bounds":{"left":0.8871528,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXButton","text":"You can't unmute someone else","depth":13,"bounds":{"left":0.9149306,"top":0.50666666,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Aneliya Angelova","depth":13,"bounds":{"left":0.9454861,"top":0.5088889,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Aneliya Angelova","depth":17,"bounds":{"left":0.87951386,"top":0.6205556,"width":0.088541664,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"You’re continuously framed","depth":13,"bounds":{"left":0.82256943,"top":0.7644445,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":false,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"Backgrounds and effects","depth":13,"bounds":{"left":0.853125,"top":0.7644445,"width":0.030555556,"height":0.04888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXButton","text":"More options for Lukas Kovalik","depth":13,"bounds":{"left":0.8836806,"top":0.76666665,"width":0.027777778,"height":0.044444446},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false,"is_expanded":false},{"role":"AXStaticText","text":"Lukas Kovalik","depth":17,"bounds":{"left":0.753125,"top":0.87833333,"width":0.06875,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXButton","text":"Others might see more of your background. Click to view your full video.","depth":14,"bounds":{"left":0.96631944,"top":0.875,"width":0.018055556,"height":0.028888889},"on_screen":true,"help_text":"","role_description":"button","subrole":"AXUnknown","is_enabled":true,"is_focused":false,"is_selected":false},{"role":"AXStaticText","text":"9:57","depth":12,"bounds":{"left":0.050347224,"top":0.9444444,"width":0.021527778,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"},{"role":"AXStaticText","text":"AM","depth":12,"bounds":{"left":0.07534722,"top":0.9444444,"width":0.017708333,"height":0.022777777},"on_screen":true,"help_text":"","role_description":"text","subrole":"AXUnknown"}]...
|
7796178685662123174
|
-2881827445049402862
|
visual_change
|
hybrid
|
NULL
|
Meet - Daily - Platform
Close tab
New Tab
Open Goo Meet - Daily - Platform
Close tab
New Tab
Open Google Gemini (⌃X)
Tabs from other devices
Open history (⇧⌘H)
Open bookmarks (⌘B)
Customize sidebar
Nikolay Yankov (Presenting)
Nikolay Yankov (Presenting)
People
6
Take notes with Gemini
Take notes with Gemini
Gemini
Gemini
Unpin Nikolay Yankov's presentation from your main screen
You can't unmute someone else's presentation
More options for Nikolay Yankov
Zoom in
Open in new window
Enter Full Screen
Pin Steliyan Georgiev to your main screen
You can't unmute someone else
More options for Steliyan Georgiev
Steliyan Georgiev
Pin Nikolay Yankov to your main screen
Mute Nikolay Yankov's microphone
More options for Nikolay Yankov
Nikolay Yankov
Pin Nikolay Ivanov to your main screen
You can't unmute someone else
More options for Nikolay Ivanov
Nikolay Ivanov
Pin Aneliya Angelova to your main screen
You can't unmute someone else
More options for Aneliya Angelova
Aneliya Angelova
You’re continuously framed
Backgrounds and effects
More options for Lukas Kovalik
Lukas Kovalik
Others might see more of your background. Click to view your full video.
9:57
AM
+FirefoxProfilesToolsWindowDaily - Platform - 8 m left100% <478• Mon 18 May 9:57:32FileEditViewHistoryBookmarksHelp→meet.google.com/agt-teir-cwt?authuser=lukas.kovalik%40jiminny.comNikolay Yankov (Presenting)TớtMon 18 May 9:57YSRD83 5mi* PrOAlte x3 мСР(a Sche x© Curs |Cost Xoum xQ MCHo Pipt XJmO [URL_WITH_CREDENTIALS] owner's role to beselected when setting up aEMPROVEMENT OF OUR ERICHINIn DevД 3y-2061315 = ®Deployed@ J-19951 1 0 ••=Improve Activity TypesuggestionsAUTO-DETEGTED AGTIVETY TYPBacklogP SY-204702 ..= 1DeployedЕ 3-202720 •+=|Sidekick SMS issueDeployedCE PY-20091n .=@Steliyan GeorgievNikolay NanoY coos=Nikolay YankovAneliya Angelova9:57 AM | Daily - PlatformLukas Kovalik• 11:07...
|
49764
|
NULL
|
NULL
|
NULL
|